Recordings
The Recordings API allows you to upload video, audio, and text files, track their processing status, and retrieve transcripts and metadata once processing is complete.
Overview
Recordings are uploaded in a three-step process:
- Initiate Upload - Create a recording record and get a pre-signed upload URL
- Upload File - Upload your file directly to Azure Blob Storage using the pre-signed URL
- Complete Upload - Verify the upload and trigger AI processing
Once processing is complete, you can retrieve the full transcript, summary, and metadata.
Supported File Types
Video Formats
video/mp4- MPEG-4 videovideo/webm- WebM videovideo/quicktime- QuickTime/MOV filesvideo/x-msvideo- AVI filesvideo/x-matroska- MKV files
Audio Formats
audio/mpeg- MP3 audioaudio/wav- WAV audioaudio/ogg- OGG audioaudio/webm- WebM audioaudio/x-m4a- M4A audioaudio/flac- FLAC audio
Text Formats
text/plain- Plain text filestext/csv- CSV filesapplication/json- JSON filestext/vtt- WebVTT subtitle filestext/srt- SubRip subtitle files
File Size Limits
| Type | Maximum Size |
|---|---|
| Video | 400 MB (419,430,400 bytes) |
| Audio | 100 MB (104,857,600 bytes) |
| Text | 100 MB (104,857,600 bytes) |
Files exceeding these limits will be rejected with a 400 Bad Request error.
Recording Statuses
| Status | Description |
|---|---|
pending_upload | Upload initiated, waiting for file to be uploaded |
pending | File uploaded, waiting for processing to start |
processing | Currently being processed by AI |
completed | Processing complete, transcript and insights available |
failed | Processing failed (check processingError for details) |
Initiate Recording Upload
Creates a new recording and returns a pre-signed URL for direct upload to Azure Blob Storage.
POST /v2/projects/{projectId}/recordingsNote: Requires
read_writepermission.
Headers
| Header | Type | Required | Description |
|---|---|---|---|
x-api-key | string | Yes | Your API key (requires read_write permission) |
Content-Type | string | Yes | application/json |
Path Parameters
| Parameter | Type | Description |
|---|---|---|
projectId | string | The project’s unique identifier |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Recording name (max 200 characters) |
description | string | No | Optional description (max 1000 characters) |
filename | string | Yes | Original filename (max 500 characters) |
mimeType | string | Yes | File MIME type (see supported types above) |
fileSize | number | Yes | File size in bytes (must be positive) |
Request Example
{
"name": "User Interview - John Doe",
"description": "Interview about checkout experience",
"filename": "interview-john.mp4",
"mimeType": "video/mp4",
"fileSize": 104857600
}Response
201 Created
{
"recordingId": "507f1f77bcf86cd799439013",
"uploadUrl": "https://storage.blob.core.windows.net/container/path?sv=2021-06-08&ss=b&srt=co&sp=rwdlacx&se=2024-12-26T14:00:00Z&st=2024-12-26T12:00:00Z&spr=https&sig=...",
"blobPath": "orgId/projectId/recordingId/filename.mp4",
"expiresAt": "2024-12-26T14:00:00.000Z",
"maxFileSize": 419430400
}Response Fields
| Field | Type | Description |
|---|---|---|
recordingId | string | Unique recording identifier (use this for subsequent requests) |
uploadUrl | string | Pre-signed URL for direct upload to Azure Blob Storage |
blobPath | string | Storage path where the file will be stored |
expiresAt | string | ISO 8601 timestamp when the upload URL expires (typically 2 hours) |
maxFileSize | number | Maximum allowed file size in bytes for this file type |
Example Request
curl -X POST "https://api.yeino.com/v2/projects/507f1f77bcf86cd799439011/recordings" \
-H "x-api-key: yno_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"name": "User Interview - John Doe",
"filename": "interview-john.mp4",
"mimeType": "video/mp4",
"fileSize": 104857600
}'Error Responses
| Status Code | Error | Description |
|---|---|---|
| 400 | Bad Request | Invalid file type, size, or parameters |
| 401 | Unauthorized | Invalid or missing API key |
| 403 | Forbidden | API key requires read_write permission |
| 404 | Not Found | Project not found |
400 Bad Request Example:
{
"statusCode": 400,
"message": "File size exceeds maximum allowed size of 419430400 bytes.",
"error": "Bad Request"
}Upload File to Azure
After receiving the uploadUrl from the initiate endpoint, upload your file directly to Azure Blob Storage.
Note: This is a direct upload to Azure, not to the Yeino API. Use the
uploadUrlfrom the initiate response.
Upload Request
curl -X PUT "{uploadUrl}" \
-H "x-ms-blob-type: BlockBlob" \
-H "Content-Type: video/mp4" \
--data-binary @interview-john.mp4Headers
| Header | Type | Required | Description |
|---|---|---|---|
x-ms-blob-type | string | Yes | Must be BlockBlob |
Content-Type | string | Yes | MIME type matching the file (e.g., video/mp4) |
Important Notes
- The upload URL expires after 2 hours. Upload your file before it expires.
- Upload the file as binary data (
--data-binaryin curl). - The file size must match the
fileSizespecified in the initiate request. - After successful upload, call the complete endpoint to verify and trigger processing.
Complete Recording Upload
Called after successfully uploading the file to Azure. Verifies the upload and triggers AI processing.
POST /v2/recordings/{recordingId}/completeNote: Requires
read_writepermission.
Headers
| Header | Type | Required | Description |
|---|---|---|---|
x-api-key | string | Yes | Your API key (requires read_write permission) |
Content-Type | string | Yes | application/json |
Path Parameters
| Parameter | Type | Description |
|---|---|---|
recordingId | string | The recording ID from the initiate upload response |
Request Body (Optional)
| Field | Type | Required | Description |
|---|---|---|---|
actualFileSize | number | No | Actual file size for verification (optional) |
Request Example
{}Or with file size verification:
{
"actualFileSize": 104857600
}Response
200 OK
{
"id": "507f1f77bcf86cd799439013",
"name": "User Interview - John Doe",
"status": "processing",
"isUploaded": true,
"createdAt": "2024-12-26T10:30:00.000Z"
}Example Request
curl -X POST "https://api.yeino.com/v2/recordings/507f1f77bcf86cd799439013/complete" \
-H "x-api-key: yno_live_abc123..." \
-H "Content-Type: application/json" \
-d '{}'Error Responses
| Status Code | Error | Description |
|---|---|---|
| 400 | Bad Request | Upload not found or invalid state |
| 401 | Unauthorized | Invalid or missing API key |
| 403 | Forbidden | API key requires read_write permission |
| 404 | Not Found | Recording not found |
Get Recording Details
Retrieves full recording details including transcript, summary, and metadata if processing is complete.
GET /v2/recordings/{recordingId}Headers
| Header | Type | Required | Description |
|---|---|---|---|
x-api-key | string | Yes | Your API key (requires read permission) |
Path Parameters
| Parameter | Type | Description |
|---|---|---|
recordingId | string | The recording’s unique identifier |
Response
200 OK
{
"id": "507f1f77bcf86cd799439013",
"name": "User Interview - John Doe",
"description": "Interview about checkout experience",
"status": "completed",
"isUploaded": true,
"fileType": "video",
"originalFilename": "interview-john.mp4",
"mimeType": "video/mp4",
"fileSize": 104857600,
"fileMetadata": {
"duration": 1847.5,
"language": "en",
"speakerCount": 2,
"wordCount": 4523
},
"transcriptSummary": {
"summary": "John discussed his frustrations with the current checkout process...",
"keyTopics": ["checkout flow", "payment options", "error messages"],
"participants": ["Interviewer", "John Doe"]
},
"fullTranscript": "Welcome John. Thanks for joining us today...",
"transcript": [
{
"speaker": "Speaker 1",
"startTime": 0.5,
"endTime": 5.2,
"text": "Welcome John. Thanks for joining us today."
},
{
"speaker": "Speaker 2",
"startTime": 5.8,
"endTime": 9.1,
"text": "Thanks for having me. Happy to help."
}
],
"createdAt": "2024-12-26T10:30:00.000Z",
"processedAt": "2024-12-26T10:45:00.000Z"
}Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Recording identifier |
name | string | Recording name |
description | string | null | Optional description |
status | string | Processing status (see statuses above) |
isUploaded | boolean | Whether file has been uploaded |
fileType | string | video, audio, or text |
originalFilename | string | Original filename |
mimeType | string | File MIME type |
fileSize | number | File size in bytes |
fileMetadata | object | null | File metadata (only if processing completed) |
fileMetadata.duration | number | null | Duration in seconds (for video/audio) |
fileMetadata.language | string | null | Detected language code |
fileMetadata.speakerCount | number | null | Number of speakers detected |
fileMetadata.wordCount | number | null | Total word count |
transcriptSummary | object | null | AI-generated summary (only if processing completed) |
transcriptSummary.summary | string | Summary text |
transcriptSummary.keyTopics | string[] | Key topics identified |
transcriptSummary.participants | string[] | Participant names/speakers |
fullTranscript | string | null | Full transcript as plain text |
transcript | array | null | Transcript segments with timestamps |
transcript[].speaker | string | Speaker identifier |
transcript[].startTime | number | Start time in seconds |
transcript[].endTime | number | End time in seconds |
transcript[].text | string | Transcript text for this segment |
createdAt | string | ISO 8601 timestamp when recording was created |
processedAt | string | null | ISO 8601 timestamp when processing completed |
Example Request
curl -X GET "https://api.yeino.com/v2/recordings/507f1f77bcf86cd799439013" \
-H "x-api-key: yno_live_abc123..."Notes
- If processing is not complete (
statusispending,pending_upload, orprocessing), thetranscript,transcriptSummary, andfileMetadatafields will benull. - Use the Get Recording Status endpoint to check processing status without retrieving full details.
- Transcript segments are ordered chronologically by
startTime.
Error Responses
| Status Code | Error | Description |
|---|---|---|
| 401 | Unauthorized | Invalid or missing API key |
| 404 | Not Found | Recording not found |
Get Recording Status
Quick check to see the current processing status of a recording without retrieving full details.
GET /v2/recordings/{recordingId}/statusHeaders
| Header | Type | Required | Description |
|---|---|---|---|
x-api-key | string | Yes | Your API key (requires read permission) |
Path Parameters
| Parameter | Type | Description |
|---|---|---|
recordingId | string | The recording’s unique identifier |
Response
200 OK
{
"id": "507f1f77bcf86cd799439013",
"name": "User Interview - John Doe",
"status": "processing",
"isUploaded": true,
"createdAt": "2024-12-26T10:30:00.000Z"
}Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Recording identifier |
name | string | Recording name |
status | string | Current processing status |
isUploaded | boolean | Whether file has been uploaded |
createdAt | string | ISO 8601 timestamp when recording was created |
processedAt | string | null | ISO 8601 timestamp when processing completed (if applicable) |
processingError | object | null | Error details if status is failed |
Example Request
curl -X GET "https://api.yeino.com/v2/recordings/507f1f77bcf86cd799439013/status" \
-H "x-api-key: yno_live_abc123..."Use Cases
- Polling for completion - Check status periodically until
statusiscompleted - Error monitoring - Detect failed processing and handle errors
- Progress tracking - Show upload and processing status to users
Error Responses
| Status Code | Error | Description |
|---|---|---|
| 401 | Unauthorized | Invalid or missing API key |
| 404 | Not Found | Recording not found |
Complete Upload Workflow
Here’s a complete example of uploading and processing a recording:
// 1. Initiate upload
const initResponse = await fetch('/v2/projects/{projectId}/recordings', {
method: 'POST',
headers: {
'x-api-key': 'yno_live_abc123...',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'User Interview - John Doe',
filename: 'interview.mp4',
mimeType: 'video/mp4',
fileSize: file.size,
}),
});
const { recordingId, uploadUrl } = await initResponse.json();
// 2. Upload file to Azure
await fetch(uploadUrl, {
method: 'PUT',
headers: {
'x-ms-blob-type': 'BlockBlob',
'Content-Type': 'video/mp4',
},
body: file,
});
// 3. Complete upload
await fetch(`/v2/recordings/${recordingId}/complete`, {
method: 'POST',
headers: {
'x-api-key': 'yno_live_abc123...',
'Content-Type': 'application/json',
},
body: JSON.stringify({}),
});
// 4. Poll for completion
let status = 'processing';
while (status === 'processing' || status === 'pending') {
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
const statusResponse = await fetch(`/v2/recordings/${recordingId}/status`, {
headers: { 'x-api-key': 'yno_live_abc123...' },
});
const { status: currentStatus } = await statusResponse.json();
status = currentStatus;
}
// 5. Get full recording with transcript
const recording = await fetch(`/v2/recordings/${recordingId}`, {
headers: { 'x-api-key': 'yno_live_abc123...' },
}).then(r => r.json());
console.log(recording.transcriptSummary);
console.log(recording.transcript);For a more detailed end-to-end example, see the Complete Integration Example.