🚀 Transcript Monkey API

Integrate powerful video and audio transcription into your applications. Simple, fast, and reliable.

🌐 Base URL

https://api.transcriptmonkey.com

🎯 Getting Started

Follow these simple steps to start using the Transcript Monkey API:

  1. Sign up at transcriptmonkey.com using Google OAuth
  2. Navigate to the API section in your dashboard
  3. Generate an API key
  4. Use the API key in the Authorization header
Important: Save your API key immediately after generation. You won't be able to see it again.

🔐 Authentication

All API requests must include your API key in the Authorization header using Bearer token authentication:

Authorization: Bearer vt_your_api_key_here

⚡ Rate Limits & Plans

Minutes are calculated based on audio duration, not processing time.

Plan Monthly Minutes Price
Free 30 minutes total Free
Monkey Power 300 minutes (5 hours) €5/month

📡 API Endpoints

1. Transcribe from URL

Transcribe videos from Instagram or TikTok URLs.

POST /api/transcribe

Request Body:

{
  "url": "https://www.instagram.com/reel/xyz123"
}

Supported Platforms:

  • Instagram (posts, reels, stories)
  • TikTok videos

Response 202 Accepted:

{
  "success": true,
  "data": {
    "id": 123,
    "url": "https://www.instagram.com/reel/xyz123",
    "status": "queued",
    "platform": "instagram",
    "createdAt": "2025-01-17T10:30:00.000Z",
    "message": "Transcription job queued successfully"
  },
  "meta": {
    "requestId": "req_1763372018130_abc123",
    "timestamp": "2025-01-17T10:30:00.000Z"
  }
}

2. Transcribe Audio File

Upload and transcribe audio files directly.

POST /api/transcribe/audio

Request:

Content-Type: multipart/form-data

file: [audio file]

File Requirements:

  • Supported Formats: MP3, WAV, M4A, OGG, FLAC, AAC
  • Max File Size: 25 MB

Response 202 Accepted:

{
  "success": true,
  "data": {
    "id": 124,
    "status": "queued",
    "platform": "audio_upload",
    "fileSize": 1048576,
    "createdAt": "2025-01-17T10:35:00.000Z",
    "message": "Audio transcription job queued successfully"
  },
  "meta": {
    "requestId": "req_1763372318130_def456",
    "timestamp": "2025-01-17T10:35:00.000Z"
  }
}

3. Transcribe Video File

Upload and transcribe video files directly.

POST /api/transcribe/video

Request:

Content-Type: multipart/form-data

file: [video file]

File Requirements:

  • Supported Formats: MP4, AVI, MOV, MKV, WEBM
  • Max File Size: 100 MB
  • Max Duration: 45 minutes

Response 202 Accepted:

{
  "success": true,
  "data": {
    "id": 125,
    "status": "queued",
    "platform": "video_upload",
    "fileSize": 5242880,
    "createdAt": "2025-01-17T10:40:00.000Z",
    "message": "Video transcription job queued successfully"
  },
  "meta": {
    "requestId": "req_1763372418130_ghi789",
    "timestamp": "2025-01-17T10:40:00.000Z"
  }
}

4. Get Transcription Status

Retrieve a specific transcription by ID.

GET /api/transcriptions/{id}

Response 200 OK:

{
  "success": true,
  "data": {
    "id": 123,
    "userId": 456,
    "anonymousId": null,
    "platform": "instagram",
    "url": "https://www.instagram.com/reel/xyz123",
    "title": "Video Title",
    "status": "completed",
    "transcriptText": "This is the transcribed text from the video...",
    "audioDuration": 120,
    "fileSize": 2048576,
    "errorMessage": null,
    "processingTime": 45,
    "viaApi": true,
    "createdAt": "2025-01-17T10:30:00.000Z",
    "completedAt": "2025-01-17T10:31:30.000Z"
  },
  "meta": {
    "requestId": "req_1763372518130_jkl012",
    "timestamp": "2025-01-17T10:45:00.000Z"
  }
}

Status Values:

  • queued - Job is waiting to be processed
  • processing - Currently transcribing
  • completed - Transcription successful
  • failed - Transcription failed (see errorMessage)

5. List Transcriptions

Get paginated list of your transcriptions.

GET /api/transcriptions

Query Parameters:

  • page (optional, default: 1) - Page number
  • limit (optional, default: 20, max: 100) - Items per page
  • status (optional) - Filter by status (queued, processing, completed, failed)

Example Request:

GET /api/transcriptions?page=2&limit=10&status=completed

Response 200 OK:

{
  "success": true,
  "data": [
    {
      "id": 125,
      "platform": "video_upload",
      "status": "completed",
      "transcriptText": "Transcription text here...",
      "audioDuration": 180,
      "createdAt": "2025-01-17T10:40:00.000Z",
      "completedAt": "2025-01-17T10:43:00.000Z"
    },
    {
      "id": 124,
      "platform": "audio_upload",
      "status": "processing",
      "transcriptText": null,
      "audioDuration": null,
      "createdAt": "2025-01-17T10:35:00.000Z",
      "completedAt": null
    }
  ],
  "meta": {
    "requestId": "req_1763372618130_mno345",
    "timestamp": "2025-01-17T10:50:00.000Z",
    "pagination": {
      "page": 2,
      "limit": 10,
      "total": 45,
      "totalPages": 5
    }
  }
}

6. Delete Transcription

Delete a specific transcription.

DELETE /api/transcriptions/{id}

Response 200 OK:

{
  "success": true,
  "data": {
    "message": "Transcription deleted successfully",
    "id": 123
  },
  "meta": {
    "requestId": "req_1763372718130_pqr678",
    "timestamp": "2025-01-17T10:55:00.000Z"
  }
}

⚠️ Error Responses

All errors follow this format:

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message",
    "details": "Additional error context (optional)"
  },
  "meta": {
    "requestId": "req_1763372818130_stu901",
    "timestamp": "2025-01-17T11:00:00.000Z"
  }
}

Common Error Codes

HTTP Status Error Code Description
400 INVALID_REQUEST Missing or invalid parameters
400 INVALID_URL URL format is invalid or unsupported platform
400 FILE_TOO_LARGE Uploaded file exceeds size limit
401 AUTH_REQUIRED Missing or invalid API key
401 INVALID_TOKEN API key is invalid or expired
403 USAGE_LIMIT_EXCEEDED Monthly transcription limit reached
404 NOT_FOUND Transcription not found or access denied
429 RATE_LIMIT_EXCEEDED Too many requests
500 INTERNAL_SERVER_ERROR Server error occurred

Example Error Response:

{
  "success": false,
  "error": {
    "code": "USAGE_LIMIT_EXCEEDED",
    "message": "Monthly transcription limit of 30 minutes exceeded. Upgrade to Monkey Power for 300 minutes.",
    "details": "Used: 32 minutes, Limit: 30 minutes"
  },
  "meta": {
    "requestId": "req_1763372918130_vwx234",
    "timestamp": "2025-01-17T11:05:00.000Z"
  }
}

💻 Code Examples

cURL - Transcribe URL

curl -X POST https://api.transcriptmonkey.com/transcribe \
  -H "Authorization: Bearer vt_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.instagram.com/reel/xyz123"}'

cURL - Upload Audio File

curl -X POST https://api.transcriptmonkey.com/transcribe/audio \
  -H "Authorization: Bearer vt_your_api_key_here" \
  -F "file=@/path/to/audio.mp3"

JavaScript (Node.js)

const axios = require('axios');

const API_KEY = 'vt_your_api_key_here';
const BASE_URL = 'https://api.transcriptmonkey.com';

// Transcribe from URL
async function transcribeURL(url) {
  try {
    const response = await axios.post(
      `${BASE_URL}/transcribe`,
      { url },
      {
        headers: {
          'Authorization': `Bearer ${API_KEY}`,
          'Content-Type': 'application/json'
        }
      }
    );
    return response.data;
  } catch (error) {
    console.error('Error:', error.response.data);
    throw error;
  }
}

// Get transcription status
async function getTranscription(id) {
  try {
    const response = await axios.get(
      `${BASE_URL}/transcriptions/${id}`,
      {
        headers: {
          'Authorization': `Bearer ${API_KEY}`
        }
      }
    );
    return response.data;
  } catch (error) {
    console.error('Error:', error.response.data);
    throw error;
  }
}

// Usage
(async () => {
  const job = await transcribeURL('https://www.instagram.com/reel/xyz123');
  console.log('Job created:', job.data.id);

  // Poll for completion
  const checkStatus = setInterval(async () => {
    const result = await getTranscription(job.data.id);
    console.log('Status:', result.data.status);

    if (result.data.status === 'completed') {
      console.log('Transcript:', result.data.transcriptText);
      clearInterval(checkStatus);
    } else if (result.data.status === 'failed') {
      console.error('Failed:', result.data.errorMessage);
      clearInterval(checkStatus);
    }
  }, 5000); // Check every 5 seconds
})();

Python

import requests
import time

API_KEY = 'vt_your_api_key_here'
BASE_URL = 'https://api.transcriptmonkey.com'

headers = {
    'Authorization': f'Bearer {API_KEY}',
    'Content-Type': 'application/json'
}

# Transcribe from URL
def transcribe_url(url):
    response = requests.post(
        f'{BASE_URL}/transcribe',
        json={'url': url},
        headers=headers
    )
    return response.json()

# Get transcription status
def get_transcription(transcription_id):
    response = requests.get(
        f'{BASE_URL}/transcriptions/{transcription_id}',
        headers=headers
    )
    return response.json()

# Upload audio file
def transcribe_audio(file_path):
    with open(file_path, 'rb') as f:
        files = {'file': f}
        headers_multipart = {'Authorization': f'Bearer {API_KEY}'}
        response = requests.post(
            f'{BASE_URL}/transcribe/audio',
            files=files,
            headers=headers_multipart
        )
    return response.json()

# Usage example
if __name__ == '__main__':
    # Create transcription job
    job = transcribe_url('https://www.instagram.com/reel/xyz123')
    transcription_id = job['data']['id']
    print(f"Job created: {transcription_id}")

    # Poll for completion
    while True:
        result = get_transcription(transcription_id)
        status = result['data']['status']
        print(f"Status: {status}")

        if status == 'completed':
            print(f"Transcript: {result['data']['transcriptText']}")
            break
        elif status == 'failed':
            print(f"Failed: {result['data']['errorMessage']}")
            break

        time.sleep(5)  # Wait 5 seconds before checking again

PHP

<?php

$apiKey = 'vt_your_api_key_here';
$baseUrl = 'https://api.transcriptmonkey.com';

// Transcribe from URL
function transcribeURL($url) {
    global $apiKey, $baseUrl;

    $ch = curl_init("$baseUrl/transcribe");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        "Authorization: Bearer $apiKey",
        "Content-Type: application/json"
    ]);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['url' => $url]));

    $response = curl_exec($ch);
    curl_close($ch);

    return json_decode($response, true);
}

// Get transcription
function getTranscription($id) {
    global $apiKey, $baseUrl;

    $ch = curl_init("$baseUrl/transcriptions/$id");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        "Authorization: Bearer $apiKey"
    ]);

    $response = curl_exec($ch);
    curl_close($ch);

    return json_decode($response, true);
}

// Usage
$job = transcribeURL('https://www.instagram.com/reel/xyz123');
$transcriptionId = $job['data']['id'];
echo "Job created: $transcriptionId\n";

// Poll for completion
do {
    sleep(5);
    $result = getTranscription($transcriptionId);
    $status = $result['data']['status'];
    echo "Status: $status\n";
} while ($status !== 'completed' && $status !== 'failed');

if ($status === 'completed') {
    echo "Transcript: " . $result['data']['transcriptText'] . "\n";
} else {
    echo "Failed: " . $result['data']['errorMessage'] . "\n";
}

✨ Best Practices

1. Polling

Transcription jobs are asynchronous. Poll the /api/transcriptions/{id} endpoint every 5-10 seconds to check status.

2. Error Handling

Always check the success field and handle errors gracefully. Implement proper retry logic for transient errors.

3. Rate Limiting

Implement exponential backoff if you receive 429 errors. Start with a 1-second delay and double it with each subsequent retry.

4. API Key Security

  • Never expose API keys in client-side code
  • Store keys securely in environment variables
  • Rotate keys periodically
  • Use different keys for development and production

5. File Uploads

  • Validate file size and format before uploading
  • Use multipart/form-data for file uploads
  • Handle upload progress for large files
  • Compress files when possible to save bandwidth

💬 Support