Skip to content

Upload audio and video to Speak AI and read insights

Upload audio and video to Speak AI, list your media library, poll processing status, read the transcript and insights, and run the analysis again.

Updated View as MarkdownAsk ClaudeOpen in ChatGPTllms.txt

The Speak AI API exposes 13 media 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.

This media collection of endpoints enables operation of list, insights, transcript and export.

Uploading audio or video

When uploading a file, a media file URL (accessible to our servers) must be provided.

This can be a publicly accessible URL hosted by yourselves or a third-party.

You can upload files directly to our storage (AWS S3 bucket) and upload the file using the returned URL.

Step 2, PUT the file to the presigned URL

This step targets the storage host returned in preSignedUrl, not api.speakai.co, so it is described here rather than as a Speak AI endpoint.

PUT Request to Upload Audio File

This endpoint allows you to upload an audio file (in this case, an MP3 file) to an Amazon S3 bucket. The request is made using the HTTP PUT method, which is commonly used for updating resources.

Request URL

https://xs3.amazonaws.com/video/1622234682034-medianame.mp3?AWSAccessKeyId=x&Content-Type=audio/mp3&Expires=1622245482&Signature=nQWU4yxBuUjQJD1yTr92qblQx6s=&x-amz-acl=public-read

Query Parameters

  • AWSAccessKeyId: Your AWS access key ID, used for authentication.

  • Content-Type: Specifies the media type of the resource being uploaded (in this case, audio/mp3).

  • Expires: A timestamp indicating when the URL will expire.

  • Signature: A signature for authentication, ensuring the request is valid.

  • x-amz-acl: Sets the access control list (ACL) for the uploaded file. Here, it is set to public-read, allowing public access to the file.

Request Body

The request does not specify a body type, indicating that the audio file is uploaded directly to the specified URL.

Expected Response

The response from a successful upload typically includes:

  • A confirmation of the upload status (e.g., HTTP status code 200 OK).

  • Metadata about the uploaded file, such as its URL and size.

Ensure that the audio file being uploaded adheres to the specified content type and that all required parameters are included in the request.

What can you do with the media endpoints?

Speak AI groups these 13 endpoints under the media resource. Each entry below links to the full reference for that endpoint further down this page.

List

GET/media

If you are looking for a paginated, sorted and filtered listing of your media library.

  • You can pass userId in params to get data for a user. (Only for enterprise use cases)

Parameters

Parameter In Type Required Description
mediaType query string No audio, video, text
page query integer No Default 1st page
pageSize query integer No Default 50
sortBy query string No Default Created At in Descending order Sort by: Created At, positive, neutral, negative asc or desc
filterMedia query integer No 0 – Uploaded 1 – Assigned Media to a User 2 – Uploaded OR Assigned Default: 0
filterName query string No Search from media name, keywords, labels, faces, brands, people, locations and transcription.
folderId query string No Pass folderId to fetch only those records
Example request
curl -X GET 'https://api.speakai.co/v1/media?mediaType=audio&page=1&pageSize=50&sortBy=createdAt%3Adesc&filterMedia=0&folderId=568sd56899' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
Response

200 OK

Response body, application/json.

Field Type
status string
data object
data.totalCount integer
data.pages integer
data.mediaList object[]
data.mediaList – 12 more fields
Field Type Description
duration object
duration.inSecond string
duration.start string
duration.end string
privacyMode string
processingProgress string
state string
remark string
_id string
sentiment any[]
mediaId string
name string
description string
createdAt string (date-time)
thumbnailUrl string A signed link to the video’s thumbnail, custom or automatic. Present only when the file has one. It expires, so do not store it.

Example response (success), application/json.

{
  "status": "success",
  "data": {
    "totalCount": 71,
    "pages": 71,
    "mediaList": [
      {
        "duration": {
          "inSecond": "60",
          "start": "0:00:00",
          "end": "0:01:00.182"
        },
        "privacyMode": "Public",
        "processingProgress": "100",
        "state": "processed",
        "remark": "",
        "_id": "5f46c87668ee9913005e5bef",
        "sentiment": [],
        "mediaId": "50ek03r4kebud105",
        "name": "vatsal-30",
        "description": "url-test",
        "createdAt": "2020-08-26T20:39:18.870Z"
      }
    ]
  }
}

Update meta-data

PUT/media/{mediaId}

If you want to rename, edit description or add a tag to your media, you can do it here.

Parameters

Parameter In Type Required Description
mediaId path string Yes

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
createdAt string The creation date to store on the file. Optional. An empty string is allowed, but the controller only writes the value when it is truthy, so an empty string does not clear the existing date.
description string A short description for the file. Optional. Trimmed. An empty string is allowed by validation, but the controller only writes a non empty value, so you cannot clear the description this way.
folderId string The id of the folder you want to move the file into. Optional. An empty string is allowed but is treated as no change.
mediaId string Ignored. The server takes the media id from the path, not from the body. Optional. An empty string is allowed. Accepted by validation and never destructured by the controller.
manageBy string The id of the user you want the file assigned to. Optional. An empty string is allowed but is treated as no change. Stored as a reference to a user record (media model: Schema.Types.ObjectId, ref ‘User’).
name string, required The new title for the file. Required. Minimum length 1. This is the only property the controller always writes, so every update overwrites the title.
remark string A note stored with the file. Optional. An empty string is allowed but is treated as no change.
status string The workflow status of the file. Optional and unconstrained by the schema, so any string passes validation. The media model recognizes ‘’, pending, progress, completed and pendingPayment, and the update runs through findOneAndUpdate without runValidators, so the model enum is not enforced on this path. Only written when not empty.
tags string[] The full list of tags for the file. The list you send replaces the existing one. Optional. Items are strings and empty strings are allowed. There is no cap on the number of items. Only written when the property is present, and an empty array is truthy so it does clear the tags.
Example request
curl -X PUT 'https://api.speakai.co/v1/media/MEDIA_ID' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "update-1",
  "description": "description-1",
  "tags": [
    "work",
    "personal"
  ]
}'
Response

200 OK

Response body, application/json.

Field Type
status string
message string

Example response (Update Media data - success), application/json.

{
  "status": "success",
  "message": "Updated successfully."
}

404 Not Found

Response body, application/json.

Field Type
status string
requestId string
code integer
message string
hints string[]

Example response (Update Media data - failure), application/json.

{
  "status": "failed",
  "requestId": "7ed88c1e-e1ee-44b0-afa5-50041d2b2309",
  "code": 404,
  "message": "Media does not exist!",
  "hints": [
    "The requested operation failed because a resource associated with the request could not be found."
  ]
}

Delete File

DELETE/media/{mediaId}

If you want to remove media from your library - you can do it here.

We can revert the changes if you send us a request.

Parameters

Parameter In Type Required Description
mediaId path string Yes
Example request
curl -X DELETE 'https://api.speakai.co/v1/media/MEDIA_ID' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
Response

200 Success

The spec records this status code with no example body.

Set a custom thumbnail

PUT/media/{mediaId}/thumbnail

Replace a video’s thumbnail with your own image or with a frame from the video. Send exactly one of:

  • an image file as multipart form data in the image field, for example -F 'image=@cover.png'
  • JSON { "url": "https://..." }, a public https link to an image, which the server downloads
  • JSON { "seekSec": 12.5 }, to use the video frame at that many seconds from the start

The image must be JPEG, PNG or WebP and at most 10 MB. The server checks the file’s content, not its name or declared type, so a GIF is refused. A url must be https and point to a public address, every redirect included. The server follows up to 3 redirects and gives up after 8 seconds.

A frame request answers 202 straight away and the frame is saved in the background. A seekSec past the end of the video uses the frame one second before the end. To follow it, poll GET /media/status/{mediaId} and read data.thumbnail: pending is true while the frame is being made, error says why it failed, and once it is saved url points to the new frame and source is custom. While a frame request for the video is still running, another one returns 409. A request that has not finished after 5 minutes no longer blocks a new one.

Each change replaces the current thumbnail and deletes the previous custom image. There is no way back to the automatic thumbnail. Only a video can have a thumbnail, and a frame cannot be taken from an archived video. You need permission to edit media.

Errors

  • 400 when the request does not carry exactly one of image, url and seekSec: “Send exactly one of an image file, an https url or seekSec.”
  • 400 when url is not https or seekSec is below 0, with the validation message.
  • 400 when the media is not a video: “Only a video can have a thumbnail.”
  • 400 when the image is not a JPEG, PNG or WebP file: “Use one JPEG, PNG or WebP image of up to 10 MB.”
  • 400 when the link is blocked or cannot be downloaded: “That image url could not be downloaded.”
  • 400 when a frame is asked of an archived video, or of one whose file Speak does not hold: “A frame cannot be taken from this video.”
  • 400 when the frame service refuses the request: “That frame could not be taken.”
  • 403 when you do not have permission to edit media.
  • 404 when the media does not exist.
  • 409 when a frame is already being taken for this video.
  • 413 when the image is larger than 10 MB: “Use one JPEG, PNG or WebP image of up to 10 MB.”
  • 503 when the frame service is busy: “Thumbnails are busy right now. Try again in a minute.”

Parameters

Parameter In Type Required Description
mediaId path string Yes Id of the video.

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
url string (uri) A public https link to a JPEG, PNG or WebP image of up to 10 MB. The server downloads it. Send this or seekSec, not both.
seekSec number Use the video frame at this many seconds from the start. A value past the end uses the frame one second before the end. Send this or url, not both.
Example request
curl -X PUT 'https://api.speakai.co/v1/media/b4994aa1267c/thumbnail' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
  -H 'Content-Type: application/json' \
  -d '{
  "url": "https://example.com/images/cover.png"
}'
Response

200 The image is saved as the thumbnail

Response body, application/json.

Field Type Description
status string success on every 2xx response. One of: success .
data object
data.thumbnail object
data.thumbnail – 2 more fields
Field Type Description
url string A signed link to the new thumbnail. It expires, so do not store it.
source string custom for a thumbnail you set. One of: custom .

202 The frame request is accepted and runs in the background

Response body, application/json.

Field Type Description
status string success on every 2xx response. One of: success .
data object
data.thumbnail object
data.thumbnail – 1 more field
Field Type Description
pending boolean Always true. The frame is still being taken. One of: true .

400 Not exactly one of image, url and seekSec, an unsupported image, a link that cannot be downloaded, or a frame that cannot be taken

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.

403 You do not have permission to edit media

Response body, application/json.

Field Type Description
status string failed. One of: failed .
message string What went wrong.

404 The media 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.

409 A frame is already being taken for this video

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.

413 The image is larger than 10 MB

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.

503 The frame service is busy

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.

Insights

GET/media/insight/{mediaId}

Load the results of analysis (sentiment, transcription, named entities, etc) for your media object here.

  • You can pass userId in params to get specifically for any user.

Parameters

Parameter In Type Required Description
mediaId path string Yes
Example request
curl -X GET 'https://api.speakai.co/v1/media/insight/5a4690abf255' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
Response

200 OK

Response body, application/json.

Field Type
status string
data object
data – 20 more fields
Field Type Description
insight object
duration object
duration.inSecond string
duration.end string
duration.start string
summary object
summary.original object
tags any[]
translationSource object Present only on a file Speak AI created by translating another one. It says whether the original source-language transcript can be read, so a client can offer the control without fetching the transcript. Fetch the transcript itself from GET /media/transcript/{mediaId}/source, which documents every reason value.
translationSource.available boolean
translationSource.reason string Why the original cannot be read. Present only when available is false.
translationSource.sourceMediaId string
translationSource.sourceLanguage string
translationSource.mediaType string
isTranscriptionOnly boolean
processingProgress string
state string
remark string
sentiment object[]
sentiment[].document object
sentiment[].sentences object[]
createdAt string (date-time)
updatedAt string (date-time)
name string
description string
publishedUrl string
mediaId string
originalCreatedAt string (date-time)
faceSpriteImg string
transcriptRevision integer Revision of the transcript. Starts at 0 and increases by one on every saved change to the transcript. Send it back as expectedTranscriptRevision when you save the transcript, label a passage or comment on one.
thumbnail object The video’s thumbnail. An empty object when the file has none, which includes every audio file and text note. Use it to follow a frame asked for with PUT /media/{mediaId}/thumbnail: pending is true while the frame is being made, and error is set when it failed, while url still shows the previous thumbnail.
thumbnail.url string A signed link to the current thumbnail. Present only when the file has one. It expires, so do not store it.
thumbnail.source string auto for the thumbnail Speak AI made, custom for one you set. Present only when the file has a thumbnail. One of: auto, custom .
thumbnail.pending boolean Present and true while a requested frame is still being made.
thumbnail.error string Why the last requested frame was not saved, for example “The frame took too long. Try again.” Present only when it failed.
insight – 23 more fields
Field Type
isAnalyze boolean
transcript object[]
faces any[]
keywords object[]
keywords[].isDeleted boolean
keywords[].instances object[]
keywords[].id integer
keywords[].name string
labels any[]
brands any[]
topics object[]
topics[].isDeleted boolean
topics[].instances object[]
topics[].id integer
topics[].name string
people any[]
locations any[]
arts any[]
dates any[]
events any[]
geopolitical any[]
languages any[]
laws any[]
money any[]
ordinals any[]
percentages any[]
quantities any[]
times any[]
cardinals any[]
nationalities any[]
products any[]
transcript – 6 more fields
Field Type
id integer
text string
confidence number
speakerId integer
language string
instances object[]
instances[].adjustedStart string
instances[].adjustedEnd string
instances[].start string
instances[].end string
keywords[].instances – 4 more fields
Field Type
adjustedStart string
adjustedEnd string
start string
end string
topics[].instances – 4 more fields
Field Type
adjustedStart string
adjustedEnd string
start string
end string
summary.original – 2 more fields
Field Type
text string
createdAt string (date-time)
sentiment[].document – 3 more fields
Field Type
Negative integer
Neutral integer
Positive integer
sentiment[].sentences – 4 more fields
Field Type
id integer
instances any[]
score object
score.compound integer
score.neg integer
score.neu integer
score.pos integer
text string

Example response (success), application/json. Arrays are shortened to one entry and long strings are cut.

{
  "status": "success",
  "data": {
    "insight": {
      "isAnalyze": true,
      "transcript": [
        {
          "id": 1,
          "text": "Both. Hello hello good how are you?",
          "confidence": 0.8278,
          "speakerId": 1,
          "language": "en-US",
          "instances": [
            {
              "adjustedStart": "0:00:00",
              "adjustedEnd": "0:00:05.92",
              "start": "0:00:00",
              "end": "0:00:05.92"
            }
          ]
        }
      ],
      "faces": [],
      "keywords": [
        {
          "isDeleted": false,
          "instances": [
            {
              "adjustedStart": "0:00:08.44",
              "adjustedEnd": "0:00:13.84",
              "start": "0:00:08.44",
              "end": "0:00:13.84"
            }
          ],
          "id": 1,
          "name": "company"
        }
      ],
      "labels": [],
      "brands": [],
      "topics": [
        {
          "isDeleted": false,
          "instances": [
            {
              "adjustedStart": "0:00:00",
              "adjustedEnd": "0:00:47.744",
              "start": "0:00:00",
              "end": "0:00:47.744"
            }
          ],
          "id": 1,
          "name": "Promotions"
        }
      ],
      "people": [],
      "locations": [],
      "arts": [],
      "dates": [],
      "events": [],
      "geopolitical": [],
      "languages": [],
      "laws": [],
      "money": [],
      "ordinals": [],
      "percentages": [],
      "quantities": [],
      "times": [],
      "cardinals": [],
      "nationalities": [],
      "products": []
    },
    "duration": {
      "inSecond": "47",
      "end": "0:00:47.744",
      "start": "0:00:00"
    },
    "summary": {
      "original": {
        "text": "",
        "createdAt": "2020-09-04T16:16:19.118Z"
      }
    },
    "tags": [],
    "isTranscriptionOnly": false,
    "processingProgress": "100",
    "state": "processed",
    "remark": "",
    "sentiment": [
      {
        "document": {
          "Negative": 0,
          "Neutral": 0,
          "Positive": 0
        },
        "sentences": [
          {
            "id": 1,
            "instances": [],
            "score": {
              "compound": 0,
              "neg": 0,
              "neu": 1,
              "pos": 0
            },
            "text": "Sentence 1"
          }
        ]
      }
    ],
    "createdAt": "2020-08-22T23:05:57.000Z",
    "updatedAt": "2020-08-22T23:11:11.288Z",
    "name": "REc557e3c8f2ac42a828973c39f1d6be37",
    "description": "",
    "publishedUrl": "media/5d03a9d5d4bca272e9c8cf89/audio/1598137553998-rec557e3c8f2ac42a828973c39f1d6be37.mp3",
    "mediaId": "81c226f66705",
    "originalCreatedAt": "2020-11-08T16:40:10.706Z",
    "faceSpriteImg": "",
    "transcriptRevision": 3
  }
}

Example response (Insights - notUploaded), application/json.

{
  "status": 200,
  "state": "notUploaded",
  "message": {
    "insight": {
      "isAnalyze": false,
      "faces": [],
      "keywords": [],
      "sentiments": [],
      "emotions": [],
      "labels": [],
      "brands": [],
      "topics": [],
      "transcript": [],
      "speakers": []
    },
    "duration": {
      "inSecond": "0"
    },
    "createdAt": "2019-09-25T14:32:19.000Z",
    "_id": "5d8b7a730838363d90a17e86",
    "videoId": "QHw2hPhk9-R7rrlPKBZk-FBY9P8rDBV",
    "name": "ForBiggerBlazes - Copy",
    "description": "",
    "privacyMode": "Public",
    "size": "0",
    "processingProgress": "0",
    "state": "notUploaded",
    "publishedUrl": "video/5cc37a170eb2173efcfc1f7d/1569421938203-ForBiggerBlazesCopymp4.mp4",
    "videoFormat": 1,
    "sourceLanguage": "en-US",
    "order": 0,
    "__v": 0
  }
}

Re-analyze a media file or text note

GET/media/reanalyze/{mediaId}

Run the Speak AI analysis again over a record that has already been processed, and replace the insights it produced the first time.

One route covers both kinds of record. Pass the mediaId of an uploaded audio or video file, or the mediaId of a text note, and Speak AI re-analyzes whichever record the id belongs to.

What the call does

The record moves into the preparingAnalysis state and the analysis runs in the background, so the response comes back before the new insights exist. Poll GET /media/status/{mediaId} to follow it, or subscribe to the media.reanalyzed and text.reanalyzed webhook events.

The query parameters select which parts of the analysis run again. Omit all of them to re-run the default analysis.

Parameters

Parameter In Type Required Description
mediaId path string Yes Id of the media file or text note to re-analyze.
isInsights query boolean No Re-run insight extraction.
isSentiment query boolean No Re-run sentiment analysis.
isFillerWords query boolean No Re-run filler word detection.
isEmbeddings query boolean No Rebuild the embeddings used by AI chat.
Example request
curl -X GET 'https://api.speakai.co/v1/media/reanalyze/3f8d1ec6ca39?isInsights=true&isSentiment=true&isFillerWords=true&isEmbeddings=true' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
Response

200 OK

Response body, application/json.

Field Type
status string
message string

Example response (Re-analysis started), application/json.

{
  "status": "success",
  "message": "Leon Wednesday Meeting re-analyzed successfully!"
}

Example response (Record already in the failed state), application/json.

{
  "status": "success",
  "message": "Media analysis failed. Please contact support if you need assistance."
}

500 Internal Server Error

Response body, application/json.

Field Type
status string
requestId string
code integer
message string
hints string[]

Example response (Internal server error), application/json.

{
  "status": "failed",
  "requestId": "ca665625-645e-438a-867d-366a6e3f133a",
  "code": 500,
  "message": "Something went wrong. Please try again later.",
  "hints": [
    "Something went wrong. Please try again later."
  ]
}

Update Transcript Speakers

PUT/media/speakers/{mediaId}

Request Description

This API endpoint allows you to update speaker names in the transcription of a media object.

Endpoint

PUT /v1/media/speakers/{mediaId}

Method

PUT

Purpose

The purpose of this request is to update the speaker information associated with a specific media object. This includes modifying the names of the speakers in the transcription data.

Input Parameters
  • mediaId (path parameter): The unique identifier for the media object whose speaker information you wish to update.

  • Request Body: The request body should be a JSON array containing objects with the following structure:

  • id (string): The unique identifier for the speaker (ORIGINAL).

  • name (string): The new name of the speaker.

Response Structure

The response will return a JSON object containing the following fields:

  • status: Indicates the status of the request.

  • message: String

Example Response
{
 "status": "",
 "message": ""
}
Notes
  • Ensure that the mediaId provided in the URL corresponds to an existing media object.

  • The request body must be formatted as a JSON array, even if updating a single speaker.

  • The response will confirm the status of the update operation, along with any relevant data about the media analysis.

Request rules. The body is an array, one entry per speaker you are relabelling, and every entry needs id and name. Omit segmentIds to relabel every segment for that speaker, or pass them to limit the rename to one paragraph. Pass mergeIntoId to merge this speaker into an existing one.

Parameters

Parameter In Type Required Description
mediaId path string Yes

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
[].id string, required The speaker you are renaming, given as either the speaker’s current label or its numeric speaker id. Required on every array entry. Trimmed. The server matches the current label first and the numeric id second (resolveTargetSpeaker at, so a label wins when both could match.
[].name string, required The new name for that speaker. Required on every array entry. Trimmed. Reusing another speaker’s name returns 400 unless you also send mergeIntoId on the same entry.
[].segmentIds number[] The transcript segment ids you want renamed. Send it to limit the change to one paragraph, and leave it out to rename every segment belonging to that speaker. Optional. Items must be numbers. No minimum or maximum item count.
[].mergeIntoId string The id of the speaker you are merging this one into. Sending it confirms you meant to combine two speakers, so the duplicate name check is skipped for this entry. Optional. An empty string is allowed, and an empty string counts as not set.
Example request
curl -X PUT 'https://api.speakai.co/v1/media/speakers/b4994aa1267c' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
  -H 'Content-Type: application/json' \
  -d '[
  {
    "id": "0",
    "name": "Vatsal"
  }
]'
Response

200 OK

Response body, application/json.

Field Type
status string
data object
data – 17 more fields
Field Type
insight object
duration object
duration.inSecond string
duration.end string
duration.start string
summary object
summary.original object
tags any[]
isTranscriptionOnly boolean
processingProgress string
state string
remark string
sentiment object[]
sentiment[].document object
sentiment[].sentences object[]
createdAt string (date-time)
updatedAt string (date-time)
name string
description string
publishedUrl string
mediaId string
originalCreatedAt string (date-time)
faceSpriteImg string
insight – 23 more fields
Field Type
isAnalyze boolean
transcript object[]
faces any[]
keywords object[]
keywords[].isDeleted boolean
keywords[].instances object[]
keywords[].id integer
keywords[].name string
labels any[]
brands any[]
topics object[]
topics[].isDeleted boolean
topics[].instances object[]
topics[].id integer
topics[].name string
people any[]
locations any[]
arts any[]
dates any[]
events any[]
geopolitical any[]
languages any[]
laws any[]
money any[]
ordinals any[]
percentages any[]
quantities any[]
times any[]
cardinals any[]
nationalities any[]
products any[]
transcript – 6 more fields
Field Type
id integer
text string
confidence number
speakerId integer
language string
instances object[]
instances[].adjustedStart string
instances[].adjustedEnd string
instances[].start string
instances[].end string
keywords[].instances – 4 more fields
Field Type
adjustedStart string
adjustedEnd string
start string
end string
topics[].instances – 4 more fields
Field Type
adjustedStart string
adjustedEnd string
start string
end string
summary.original – 2 more fields
Field Type
text string
createdAt string (date-time)
sentiment[].document – 3 more fields
Field Type
Negative integer
Neutral integer
Positive integer
sentiment[].sentences – 4 more fields
Field Type
id integer
instances any[]
score object
score.compound integer
score.neg integer
score.neu integer
score.pos integer
text string

Example response (success), application/json. Arrays are shortened to one entry and long strings are cut.

{
  "status": "success",
  "data": {
    "insight": {
      "isAnalyze": true,
      "transcript": [
        {
          "id": 1,
          "text": "Both. Hello hello good how are you?",
          "confidence": 0.8278,
          "speakerId": 1,
          "language": "en-US",
          "instances": [
            {
              "adjustedStart": "0:00:00",
              "adjustedEnd": "0:00:05.92",
              "start": "0:00:00",
              "end": "0:00:05.92"
            }
          ]
        }
      ],
      "faces": [],
      "keywords": [
        {
          "isDeleted": false,
          "instances": [
            {
              "adjustedStart": "0:00:08.44",
              "adjustedEnd": "0:00:13.84",
              "start": "0:00:08.44",
              "end": "0:00:13.84"
            }
          ],
          "id": 1,
          "name": "company"
        }
      ],
      "labels": [],
      "brands": [],
      "topics": [
        {
          "isDeleted": false,
          "instances": [
            {
              "adjustedStart": "0:00:00",
              "adjustedEnd": "0:00:47.744",
              "start": "0:00:00",
              "end": "0:00:47.744"
            }
          ],
          "id": 1,
          "name": "Promotions"
        }
      ],
      "people": [],
      "locations": [],
      "arts": [],
      "dates": [],
      "events": [],
      "geopolitical": [],
      "languages": [],
      "laws": [],
      "money": [],
      "ordinals": [],
      "percentages": [],
      "quantities": [],
      "times": [],
      "cardinals": [],
      "nationalities": [],
      "products": []
    },
    "duration": {
      "inSecond": "47",
      "end": "0:00:47.744",
      "start": "0:00:00"
    },
    "summary": {
      "original": {
        "text": "",
        "createdAt": "2020-09-04T16:16:19.118Z"
      }
    },
    "tags": [],
    "isTranscriptionOnly": false,
    "processingProgress": "100",
    "state": "processed",
    "remark": "",
    "sentiment": [
      {
        "document": {
          "Negative": 0,
          "Neutral": 0,
          "Positive": 0
        },
        "sentences": [
          {
            "id": 1,
            "instances": [],
            "score": {
              "compound": 0,
              "neg": 0,
              "neu": 1,
              "pos": 0
            },
            "text": "Sentence 1"
          }
        ]
      }
    ],
    "createdAt": "2020-08-22T23:05:57.000Z",
    "updatedAt": "2020-08-22T23:11:11.288Z",
    "name": "REc557e3c8f2ac42a828973c39f1d6be37",
    "description": "",
    "publishedUrl": "media/5d03a9d5d4bca272e9c8cf89/audio/1598137553998-rec557e3c8f2ac42a828973c39f1d6be37.mp3",
    "mediaId": "81c226f66705",
    "originalCreatedAt": "2020-11-08T16:40:10.706Z",
    "faceSpriteImg": ""
  }
}

Status

GET/media/status/{mediaId}

If you need a list or a quick preview of a media you can request meta-data about media objects with this endpoint, this will include all information except for results of analysis, transcripts, etc.

Parameters

Parameter In Type Required Description
mediaId path string Yes
Example request
curl -X GET 'https://api.speakai.co/v1/media/status/MEDIA_ID' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
Response

200 OK

Response body, application/json.

Field Type
status string
data object
data – 14 more fields
Field Type Description
duration object
duration.inSecond string
duration.end string
duration.start string
tags any[]
processingProgress string
state string
remark string
_id string
createdAt string (date-time)
updatedAt string (date-time)
name string
description string
publishedUrl string
mediaId string
originalCreatedAt string (date-time)
thumbnail object The video’s thumbnail. An empty object when the file has none, which includes every audio file and text note. Use it to follow a frame asked for with PUT /media/{mediaId}/thumbnail: pending is true while the frame is being made, and error is set when it failed, while url still shows the previous thumbnail.
thumbnail.url string A signed link to the current thumbnail. Present only when the file has one. It expires, so do not store it.
thumbnail.source string auto for the thumbnail Speak AI made, custom for one you set. Present only when the file has a thumbnail. One of: auto, custom .
thumbnail.pending boolean Present and true while a requested frame is still being made.
thumbnail.error string Why the last requested frame was not saved, for example “The frame took too long. Try again.” Present only when it failed.

Example response (success), application/json.

{
  "status": "success",
  "data": {
    "duration": {
      "inSecond": "47",
      "end": "0:00:47.744",
      "start": "0:00:00"
    },
    "tags": [],
    "processingProgress": "100",
    "state": "processed",
    "remark": "",
    "_id": "5f41a4d5c35d8d0fd556e075",
    "createdAt": "2020-08-22T23:05:57.000Z",
    "updatedAt": "2020-08-22T23:11:11.288Z",
    "name": "REc557e3c8f2ac42a828973c39f1d6be37",
    "description": "",
    "publishedUrl": "media/5d03a9d5d4bca272e9c8cf89/audio/1598137553998-rec557e3c8f2ac42a828973c39f1d6be37.mp3",
    "mediaId": "81c226f66705",
    "originalCreatedAt": "2020-11-08T16:40:10.706Z"
  }
}

Example response (Insights - notUploaded), application/json.

{
  "status": 200,
  "state": "notUploaded",
  "message": {
    "insight": {
      "isAnalyze": false,
      "faces": [],
      "keywords": [],
      "sentiments": [],
      "emotions": [],
      "labels": [],
      "brands": [],
      "topics": [],
      "transcript": [],
      "speakers": []
    },
    "duration": {
      "inSecond": "0"
    },
    "createdAt": "2019-09-25T14:32:19.000Z",
    "_id": "5d8b7a730838363d90a17e86",
    "videoId": "QHw2hPhk9-R7rrlPKBZk-FBY9P8rDBV",
    "name": "ForBiggerBlazes - Copy",
    "description": "",
    "privacyMode": "Public",
    "size": "0",
    "processingProgress": "0",
    "state": "notUploaded",
    "publishedUrl": "video/5cc37a170eb2173efcfc1f7d/1569421938203-ForBiggerBlazesCopymp4.mp4",
    "videoFormat": 1,
    "sourceLanguage": "en-US",
    "order": 0,
    "__v": 0
  }
}

Transcript

GET/media/transcript/{mediaId}

Parameters

Parameter In Type Required Description
mediaId path string Yes
Example request
curl -X GET 'https://api.speakai.co/v1/media/transcript/b4994aa1267c' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
Response

200 OK

Response body, application/json.

Field Type
status string
data object
data – 10 more fields
Field Type Description
folderId string
mediaType string
name string
sourceLanguage string
insight object
insight.transcript object[]
insight.speakers object[]
duration object
duration.start string
duration.end string
duration.inSecond number
createdAt string (date-time)
mediaId string
mediaUrl string
transcriptRevision integer Revision of the transcript. Starts at 0 and increases by one on every saved change to the transcript. Send it back as expectedTranscriptRevision when you save the transcript, label a passage or comment on one.
insight.transcript – 7 more fields
Field Type
id integer
text string
speakerId string
confidence integer
language string
instances object[]
instances[].start string
instances[].end string
instances[].startInSec number
instances[].endInSec number
entities object[]
entities – 6 more fields
Field Type
id string
text string
confidence number
speakerId string
language string
instances object
instances.startInSec number
instances.endInSec number
insight.speakers – 6 more fields
Field Type
id integer
name string
instances object[]
instances[].start string
instances[].end string
instances[].startInSec number
instances[].endInSec number
totalWords integer
duration integer
wpm integer

Example response (Transcript), application/json. Arrays are shortened to one entry and long strings are cut.

{
  "status": "success",
  "data": {
    "folderId": "0648e533f72c",
    "mediaType": "audio",
    "name": "vatsal",
    "sourceLanguage": "en-US",
    "insight": {
      "transcript": [
        {
          "id": 0,
          "text": "Okay. Let's do the testing for transcription.",
          "speakerId": "0",
          "confidence": 1,
          "language": "en-US",
          "instances": [
            {
              "start": "00:00:00.240",
              "end": "00:00:02.994",
              "startInSec": 0.24,
              "endInSec": 2.9940499999999997
            }
          ],
          "entities": [
            {
              "id": "1",
              "text": "Okay.",
              "confidence": 0.99782515,
              "speakerId": "0",
              "language": "en-US",
              "instances": {
                "startInSec": 0.24,
                "endInSec": 0.48
              }
            }
          ]
        }
      ],
      "speakers": [
        {
          "id": 0,
          "name": "0",
          "instances": [
            {
              "start": "00:00:00.240",
              "end": "00:00:02.994",
              "startInSec": 0.24,
              "endInSec": 2.9940499999999997
            }
          ],
          "totalWords": 10,
          "duration": 3,
          "wpm": 200
        }
      ]
    },
    "duration": {
      "start": "00:00:00.240",
      "end": "00:00:12.144",
      "inSecond": 12.144
    },
    "createdAt": "2025-10-17T17:25:57.608Z",
    "mediaId": "b4994aa1267c",
    "mediaUrl": "MEDIA_URL",
    "transcriptRevision": 3
  }
}

Update Transcript

PUT/media/transcript/{mediaId}

Replaces the transcript of a media file with the array you send. Read the transcript first with GET /media/transcript/{mediaId}, change what you need, and send the whole array back.

Avoid overwriting someone else’s save

Send expectedTranscriptRevision with the transcriptRevision you read. If anyone saved the transcript since, the request returns 409 “This transcript changed since you opened it. Reload to keep editing.” and changes nothing: read the transcript again, reapply your change, and save with the new revision. Leave it out and the save always goes through, replacing whatever is there.

A successful save increases the revision by one and returns the new value. Labels and comments on passages are then moved to follow their words in the background.

Request rules

  • transcript needs at least one sentence; an empty transcript cannot be saved.
  • Sentence id values must be unique when you send expectedTranscriptRevision.
  • Keys that are not listed below return 400.

Errors

  • 400 when the body fails validation.
  • 404 when your company has no media with that id.
  • 409 when expectedTranscriptRevision is stale.

Parameters

Parameter In Type Required Description
mediaId path string Yes Id of the media file.

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
transcript object[], required The full transcript, as an array of sentences. At least one.
expectedTranscriptRevision integer Optional. The transcriptRevision you read the transcript at. Integer, 0 or more. When it is stale the save returns 409 and nothing is written.
transcript – 9 more fields
Field Type Description
id number, required Sentence id. Must be unique across the array when you send expectedTranscriptRevision.
speakerId string, required Speaker id. Trimmed, required.
speaker object The team member matched to this speaker, when there is one. Every key may be empty or null.
speaker.userId string Matched user id.
speaker.name string Matched name.
speaker.email string Matched email.
text string, required Sentence text. Trimmed. An empty string is accepted.
confidence number, required Sentence confidence, as returned by the transcript endpoint.
language string Language code, as returned by the transcript endpoint.
score object Sentence sentiment, as returned by the transcript endpoint. Send it back so a save does not drop it.
score.compound number, required
score.neg number, required
score.neu number, required
score.pos number, required
instances object[] Timing of the sentence.
entities object[] Word-level entries, as returned by the transcript endpoint. Not validated further.
instances – 6 more fields
Field Type Description
start string, required Start time as HH:MM:SS.mmm. Required.
end string, required End time as HH:MM:SS.mmm. Required.
startInSec number
endInSec number
adjustedStart string Adjusted start time.
adjustedEnd string Adjusted end time.
Example request
curl -X PUT 'https://api.speakai.co/v1/media/transcript/b4994aa1267c' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
  -H 'Content-Type: application/json' \
  -d '{
  "transcript": [
    {
      "id": 0,
      "text": "Okay. Let'\''s do the testing for transcription.",
      "speakerId": "0",
      "confidence": 1,
      "language": "en-US",
      "instances": [
        {
          "start": "00:00:00.240",
          "end": "00:00:02.994",
          "startInSec": 0.24,
          "endInSec": 2.994
        }
      ],
      "entities": []
    }
  ],
  "expectedTranscriptRevision": 3
}'
Response

200 Success

Response body, application/json.

Field Type Description
status string success. One of: success .
message string Updated successfully.
data object
data.transcriptRevision integer The transcript revision after this save.

Example response (Success), application/json.

{
  "status": "success",
  "message": "Updated successfully.",
  "data": {
    "transcriptRevision": 4
  }
}

400 The body 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 failed validation), application/json.

{
  "status": "failed",
  "requestId": "req_0000000000000000",
  "code": 400,
  "message": "\"transcript\" must contain at least 1 items",
  "hints": [
    "The API request is invalid or improperly formed."
  ]
}

404 No media with that id in your company

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 (No media with that id in your company), application/json.

{
  "status": "failed",
  "requestId": "req_0000000000000000",
  "code": 404,
  "message": "Media details 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."
  ]
}

Source transcript of a translated file

GET/media/transcript/{mediaId}/source

Returns the transcript of the original source-language file behind a translated one, so you can read a translation against the text it came from.

Pass the media id of the translated file. Speak AI resolves the original from the translation record, either as the separate media the two-step flow keeps or, when the translation replaced the text in place, by rebuilding the original from the words the transcription engine stored.

When the original cannot be shown, the request still answers 200. Read data.available first: false carries a reason and nothing else, and true carries the transcript. There is no 404 for an unavailable original.

The sentence shape matches GET /media/transcript/{mediaId}. The rebuilt in-place original omits the per-sentence entities array; the two-step original carries whatever the source media holds. confidence on every sentence is the confidence the transcription engine reported for the original, not a measure of the translation.

Parameters

Parameter In Type Required Description
mediaId path string Yes The id of the translated media. Sending the id of the original returns available false with reason no-link.
Example request
curl -X GET 'https://api.speakai.co/v1/media/transcript/b4994aa1267c/source' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
Response

200 OK

Response body, application/json.

Field Type
status string
data object
data – 9 more fields
Field Type Description
available boolean Whether the original transcript can be shown. Everything below is present only when this is true.
reason string Why the original cannot be shown. Present only when available is false. no-link: this file is not a translation, or its translation has not finished. original-not-retained: a text note, whose original text the translation overwrote. source-deleted: the original media was deleted. source-missing: the original is not in your workspace, or your folder access does not reach it. source-not-ready: the original is still processing. source-has-no-transcript: the original holds no transcript to return. One of: no-link, original-not-retained, source-deleted, source-missing, source-not-ready, source-has-no-transcript .
sourceMediaId string The id of the original media. On an in-place translation this is the same id you asked for, because one media holds both versions.
sourceLanguage string The language the original was transcribed in. It can be auto on a file uploaded without a declared language.
mediaType string
name string
duration object
duration.start string
duration.end string
duration.inSecond number
createdAt string (date-time)
insight object
insight.transcript object[]
insight.speakers object[]
insight.transcript – 6 more fields
Field Type
id integer
text string
speakerId string
confidence number
language string
instances object[]
instances[].start string
instances[].end string
instances[].startInSec number
instances[].endInSec number
insight.speakers – 2 more fields
Field Type
id integer
name string

Example response (The original is available), application/json.

{
  "status": "success",
  "data": {
    "available": true,
    "sourceMediaId": "0648e533f72c",
    "sourceLanguage": "en-US",
    "mediaType": "audio",
    "name": "Kickoff call",
    "duration": {
      "start": "00:00:00.000",
      "end": "00:00:12.480",
      "inSecond": 12.48
    },
    "createdAt": "2026-08-20T10:14:52.117Z",
    "insight": {
      "transcript": [
        {
          "id": 0,
          "text": "Okay. Let's do the testing for transcription.",
          "speakerId": "0",
          "confidence": 0.98,
          "language": "en-US",
          "instances": [
            {
              "start": "00:00:00.240",
              "end": "00:00:02.994",
              "startInSec": 0.24,
              "endInSec": 2.994
            }
          ]
        }
      ],
      "speakers": [
        {
          "id": 0,
          "name": "Speaker 1"
        }
      ]
    }
  }
}

Example response (The original cannot be shown), application/json.

{
  "status": "success",
  "data": {
    "available": false,
    "reason": "source-not-ready"
  }
}

Upload your file with the Signed Url or External URL

POST/media/upload

If you want to add a hosted media (you must have a valid URL) to your media library, do it here.

Parameters

Please must specify mediaType as audio or video

name: String required
description: string;
url: string required; // public URL or AWS signed URL
mediaType: 'audio'; // 'video'
userId: ""; // for enterprise users only (optional)
medicalId: "" // custom media Id or medical Id for your reference (optional)
createdAt: "2021-08-09T00:13:11.717Z" // must match the date format (optional)
tags: "comma separated strings",
folderId: "folder Id" // to save in the folder
fields: { id: string, value: string } = []; (Optional)

Webhook Callback URL:

  • If you created a webhook for media events and want to receive a callback to a specific URL for this text note, you can assign callbackUrl - string in a req.body.

  • Speak will consider the callbackUrl and will skip the callbackUrl created via Webhook API.

Fields:

You can pass the id and value in the Fields array to include related to your media files.

Upload Considerations:

  • Maximum duration limit of 3 hours for a media URL.

  • The URL needs to be accessible publicly. For Example - Google Drive, Dropbox are not supported.

  • Valid YouTube URL examples are: https://www.youtube.com/watch?v=pTJ-yvNWCUE.

  • Supported File Formats are:

  • Audio - mp3 (recommended), m4a, wav, ogg, webm, m4p

  • Video - mp4 (recommended), m4v, wmv, avi, mov, flv

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
name string, required The title you want the uploaded file to have in Speak. Required. Trimmed. No maximum length and no pattern.
description string A short description stored alongside the file. Optional. Trimmed. An empty string is allowed. The schema declares a default of an empty string, but the validation middleware discards the schema defaults, so an omitted value simply stays unset.
url string, required The link Speak fetches the file from. YouTube, Google Drive, Amazon S3 and the social platforms the resolver supports (TikTok, Instagram, X, Facebook, Reddit, SoundCloud, Twitch, Dailymotion, Streamable, Snapchat, Pinterest, Tumblr, Bilibili, VK, OK.ru and Rutube) are all handled. Vimeo and Loom page links are not resolved here: import Vimeo through the connected Vimeo integration instead. Required. Plain string with no uri format check, so the server does not reject a malformed link at validation time.
mediaType string The kind of file you are uploading, and the field that decides how it is stored and what can be run on it later. Send it whenever you know which you want, including for a page link: asking for audio on a YouTube link imports the audio track only. Leave it out when you do not know, and the server works it out from better evidence than you have: it inspects the file for a direct URL, and for a page link the resolver returns the best track the platform offers, which can still be audio when no video rendition fits the size limit. Either way the stored type follows what was actually fetched. It has no default, so leaving it out is a real choice rather than a value invented on your behalf, and the only fallback is audio when nothing else can be determined. Do not send a value guessed from the file extension. A value you send is kept, which means it stops the server inspecting the file, and a video stored as audio can never be analysed as video afterwards. Lowercased before validation, so uppercase values such as VIDEO are accepted. ‘all’ is a filter value that leaked into this schema: it validates but is not a real upload type. One of: audio, video, text, media, csv, all .
sourceLanguage string The language spoken in the file, given as a transcription language code such as en-US. Optional. Any string passes, because the validator substitutes rather than rejects. An unrecognized code becomes auto. The schema declares a default of ‘en-US’, but that default is discarded by the middleware, so if you omit it the server uses the source language on your account onboarding and falls back to auto. Defined.
callbackUrl string A URL you want Speak to call when the file finishes processing. Optional. Trimmed. An empty string is allowed. Stored on the media as webhookMetaData.callbackUrl. No uri format check.
tags string Tags to attach to the file, as a single comma separated string. Optional. Declared as a union, the schema) and allows null and an empty string, so an array also passes validation. The controller only reads a string and splits it on commas, so an array is accepted and then ignored.
createdAt string The creation timestamp to store on the file instead of the time of upload. Optional. An empty string is allowed. Parsed with new Date, so send an ISO 8601 string.
isTranscriptionOnly boolean Not used by this endpoint. Nothing in the upload flow reads it. Optional. Declared with a default of false, but that default is discarded and the value is never destructured or read by the controller.
folderId string The folder you want the file to land in. If no folder with that id exists on your account, the server puts the file in your first folder. Optional. An empty string is allowed.
fields object[] Custom field values to attach to the file. Each entry pairs the id of a field you created in Speak with the value you want stored. Optional. An unconstrained array, so validation does not check the item shape and does not cap the length. The controller expects objects with id and value, checks each id against your account fields, and silently drops the ones that do not match (checkForValidFields ends with.filter(Boolean)).
Example request
curl -X POST 'https://api.speakai.co/v1/media/upload' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "Vatsal Test 1",
  "description": "Vatsal Description",
  "url": "https://kns.im/msgs/files/32dc84df-9650-4c17-b633-e80a5097ba6f.ogg",
  "mediaType": "video",
  "sourceLanguage": "he-IL",
  "tags": "your custom tags1, tag 2, tag 3",
  "fields": [
    {
      "id": "FIELD_ID_CREATED_BY_SPEAK",
      "value": "YOUR_VALUE"
    }
  ]
}'
Response

200 OK

Response body, application/json.

Field Type
status string
data object
data.mediaId string
data.state string

Example response (success), application/json.

{
  "status": "success",
  "data": {
    "mediaId": "86a36b59b38e",
    "state": "uploaded"
  }
}

Get a Signed Url

GET/media/upload/signedurl

If you have a locally saved file and you want to upload it to our system using API, you’ll have to follow through 3 simple steps:

Process

  1. Run this endpoint to retrieve an upload link for a placeholder on our storage bucket. You’ll have preSignedUrl.

  2. This preSignedUrl is your ticket to which you PUT your local file using curl or any other HTTP client.

  3. Use “Upload your file with the Signed Url or External URL” to upload your file on Speak.

How does this work?

You can find more information about uploading a file using signed URLs here. If you still find this unenlightening, shoot a message to us on success@speakai.co!

Expiry

The link will expire in 2 hours.

Parameters

Parameter In Type Required Description
mediaType query string Yes The kind of file you are uploading. It decides the storage prefix, so it has to match the real file: a video signed as audio is stored as audio and can never be analysed as video. Required. The prefix is chosen before any bytes exist, so the server cannot work it out for you: omit it and the request is rejected. Nothing is read from the extension on filename.
filename query string Yes Filename with the extension is required
mimeType query string No For example audio/mpeg, audio/mp4, audio/wav or video/mp4
Example request
curl -X GET 'https://api.speakai.co/v1/media/upload/signedurl?mediaType=audio&filename=media_name.mp3&mimeType=audio%2Fmpeg' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
Response

200 Success

The spec records this status code with no example body.

Get an API key on the Speak AI developer page.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close