Automated AI Transcription and Captions API

Use this API to submit audio for automated transcription or captions, optionally request speaker diarization, and receive the completed result at your callback URL.

This page documents automated machine transcription only. For work completed by a human transcriptionist or captioner, use the separate Human Transcription and Captions API guide.
Base URL: https://api.freetranscription.ai/customerapi Format: JSON Max upload: 5 GB

Quick Start

Submit a file and provide a callback URL. The initial response returns immediately with a job ID.

curl -X POST https://api.freetranscription.ai/customerapi/jobs \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "file=@meeting.mp3" \
  -F "service_type=transcription" \
  -F "callback_url=https://example.com/transcription-callback" \
  -F "diarization=true" \
  -F "word_timestamps=true"

Successful submission returns HTTP 202 Accepted:

{
  "job_id": "api_20260521_001500_ab12cd34ef",
  "status": "queued",
  "queue_position": 1,
  "callback_url": "https://example.com/transcription-callback",
  "service_type": "transcription",
  "diarization": true
}
Keep this job_id. It is the only public identifier for the request and stays stable even if internal processing IDs change during retry or recovery.

Authentication

Generate your API key from the API page in your FreeTranscription.AI dashboard. You can view the complete key from that page. Send it using either X-API-Key or a bearer token.

X-API-Key: YOUR_API_KEY
Authorization: Bearer YOUR_API_KEY
API jobs belong to the customer account that submitted them. Regenerating a key preserves access to that account's jobs, while the previous key stops working immediately.

Submit Audio

POST /customerapi/jobs

Use this endpoint for both direct file uploads and remote audio URL submissions.

Multipart Upload

curl -X POST https://api.freetranscription.ai/customerapi/jobs \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "file=@meeting.mp3" \
  -F "service_type=transcription" \
  -F "callback_url=https://example.com/transcription-callback" \
  -F "diarization=true" \
  -F "word_timestamps=true"
Field Required Description
file Yes, unless using audio_url Audio or video file. Supported extensions: mp3, wav, m4a, ogg, flac, webm, mp4, avi, mkv, mov, wma, aac, opus.
callback_url Yes Your HTTPS or HTTP endpoint that will receive the final JSON callback.
service_type Yes transcription returns the transcription JSON. captions returns SRT text generated with the editor caption exporter.
word_timestamps No Boolean. Enables word-level timing when available.
diarization No Boolean. Enables speaker labels and merged speaker segments.
min_speakers, max_speakers No Optional positive integers to guide diarization speaker count.

Remote Audio URL

Instead of uploading a file, send JSON with an audio_url.

curl -X POST https://api.freetranscription.ai/customerapi/jobs \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "audio_url": "https://example.com/audio/meeting.mp3",
    "service_type": "captions",
    "callback_url": "https://example.com/transcription-callback",
    "diarization": true,
    "word_timestamps": true
  }'

Status

GET /customerapi/job/{job_id}/status

Use the customer job_id returned at submission time.

curl -H "X-API-Key: YOUR_API_KEY" \
  https://api.freetranscription.ai/customerapi/job/api_20260521_001500_ab12cd34ef/status
queued Accepted and waiting for worker capacity.
processing A Salad worker has started the job.
completed The requested transcription or captions result is ready.
failed The job failed. Check last_error.
GET /customerapi/job/{job_id}/result

This endpoint returns the same result payload shape as the callback after the job completes.

Callbacks

When a job reaches completed or failed, the cron script sends a POST request to your callback_url. Return any HTTP 2xx status to mark it delivered. Non-2xx responses are retried until the configured attempt limit is reached.

Callback Headers

Header Description
Content-Type application/json
X-Customer-Job-Id The customer job ID returned by POST /customerapi/jobs.

Completed Transcription Callback

{
  "job_id": "api_20260521_001500_ab12cd34ef",
  "status": "completed",
  "result": {
    "text": "Full transcript text...",
    "segments": [
      {
        "id": 0,
        "start": 0.0,
        "end": 4.52,
        "text": "Thanks for joining the call.",
        "speaker": "SPEAKER_00"
      }
    ],
    "speaker_text": "SPEAKER_00: Thanks for joining the call."
  }
}

Completed Captions Callback

{
  "job_id": "api_20260521_001500_ab12cd34ef",
  "status": "completed",
  "result": "1\n00:00:00,000 --> 00:00:04,520\nThanks for joining the call.\n"
}

Failed Callback

{
  "job_id": "api_20260521_001500_ab12cd34ef",
  "status": "failed",
  "result": null
}

Sample Callback Scripts

Create a callback endpoint on your server, then send its URL as callback_url. Each example receives JSON, stores the complete payload in callback-payloads, and returns a JSON acknowledgement.

<?php
header('Content-Type: application/json');

$raw = file_get_contents('php://input');
$payload = json_decode($raw, true);
$jobId = is_array($payload) ? (string)($payload['job_id'] ?? '') : '';

if ($jobId === '' || json_last_error() !== JSON_ERROR_NONE) {
    http_response_code(400);
    echo json_encode(['received' => false, 'error' => 'Invalid callback JSON']);
    exit;
}

$jobId = preg_replace('/[^A-Za-z0-9_-]/', '_', $jobId);
$directory = __DIR__ . '/callback-payloads';
if (!is_dir($directory) && !mkdir($directory, 0770, true) && !is_dir($directory)) {
    http_response_code(500);
    echo json_encode(['received' => false, 'error' => 'Storage directory unavailable']);
    exit;
}

$saved = file_put_contents(
    $directory . '/' . $jobId . '.json',
    json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES),
    LOCK_EX
);
if ($saved === false) {
    http_response_code(500);
    echo json_encode(['received' => false, 'error' => 'Could not store callback']);
    exit;
}

echo json_encode(['received' => true, 'job_id' => $jobId]);

Errors

Status Meaning
400 Invalid request, missing or invalid service_type, missing callback URL, unsupported file type, or invalid options.
401 Missing, invalid, or revoked API key.
403 The customer account associated with the API key is not active.
404 Unknown route or job ID.
409 Result requested before the job is completed.
413 Uploaded file exceeds the configured size limit.
502 The job was stored, but Salad queue submission failed.
{
  "error": "callback_url must be a valid URL"
}

Reference

Endpoint Purpose
GET /customerapi/health Check service availability and configured upload size.
POST /customerapi/jobs Submit a multipart file upload or JSON remote audio URL for automated transcription or captions.
GET /customerapi/job/{job_id}/status Fetch status, queue position, callback delivery state, and timing fields.
GET /customerapi/job/{job_id}/result Fetch the final transcription JSON or captions SRT callback payload after completion.