Human Transcription and Captions API

Submit audio or video to a professional human transcriptionist or captioner. The work is charged to your Pay-As-You-Go Balance and also appears in your FreeTranscription.AI dashboard.

This is a separate product from the Automated AI Transcription and Captions API. It uses a different endpoint, pricing, options, processing workflow, and result format.
Endpoint: /customerapi/human.php One media file per request Max upload: 5 GB

Authentication and Idempotency

Use the API key generated from the API page in your dashboard. Every submission also requires a unique Idempotency-Key. Repeating the same key returns the existing job and does not charge or order the work again.

X-API-Key: YOUR_API_KEY
Idempotency-Key: your-unique-order-reference

Submit Human Work

POST/customerapi/human.php

Multipart File Upload

curl -X POST https://api.freetranscription.ai/customerapi/human.php \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Idempotency-Key: customer-order-10482" \
  -F "file=@interview.mp3" \
  -F "service_type=transcription" \
  -F "timestamp=speakerchange" \
  -F "verbatim=no" \
  -F "extra_comment=Use the supplied spelling for product names." \
  -F "callback_url=https://example.com/human-result"

Remote Media URL

curl -X POST https://api.freetranscription.ai/customerapi/human.php \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Idempotency-Key: captions-2026-08-15-01" \
  -H "Content-Type: application/json" \
  -d '{
    "audio_url": "https://example.com/media/video.mp4",
    "service_type": "captions",
    "extra_comment": "US English captions",
    "callback_url": "https://example.com/human-result"
  }'

Request Options

FieldRequiredDescription
fileOne media sourceMultipart audio or video file. Do not send with audio_url.
audio_urlOne media sourcePublic HTTP or HTTPS media URL. Do not send with file.
service_typeYestranscription or captions.
timestampNoFor transcription: none, 2min, or speakerchange. Ignored for captions.
verbatimNoFor transcription: yes or no. Ignored for captions.
extra_commentNoInstructions for the human team, up to 5,000 characters.
project_nameNoDashboard project name. Defaults to the uploaded filename.
callback_urlNoPublic HTTP or HTTPS endpoint for the completed result notification.
For captions, timestamp and verbatim values are ignored. Captions are returned as SRT.

Response and Status

A successful submission returns HTTP 202 Accepted with the Human API job details.

{
  "product": "human_transcription",
  "job_id": "hapi_20260815_120000_a1b2c3d4e5f6a7b8",
  "status": "queued",
  "service_type": "transcription",
  "timestamp": "speakerchange",
  "verbatim": "no"
}
GET/customerapi/human.php?job_id={job_id}
curl -H "X-API-Key: YOUR_API_KEY" \
  "https://api.freetranscription.ai/customerapi/human.php?job_id=hapi_..."
queuedAccepted and waiting for the human workflow.
processingThe human transcription or captions work is in progress.
completedThe inline TXT or SRT result is ready.
failedThe order could not be processed and staff have been notified.

A completed transcription response includes the TXT content directly in result. A completed captions response includes the SRT text directly in result.

Completed Transcription Result

{
  "job_id": "hapi_...",
  "status": "completed",
  "result": "Completed human transcript text."
}

Optional Customer Callback

After the human result is stored successfully, the API sends a JSON POST to callback_url. Return any HTTP 2xx response.

Delivery is limited to one immediate attempt plus three cron retries: after approximately 5 minutes, 15 minutes, and 60 minutes. After four failed attempts, delivery is marked failed, automatic retries stop, and FreeTranscription.AI staff are emailed.

Callback Headers

HeaderDescription
Content-Typeapplication/json
X-Customer-Job-IdThe Human API job ID returned at submission.
X-Human-API-Job-IdThe same Human API job ID, provided as a product-specific header.

Completed Callback

{
  "job_id": "hapi_...",
  "status": "completed",
  "result": "1\n00:00:00,000 --> 00:00:04,500\nCompleted human captions.\n"
}

The result remains available through status lookup and the customer dashboard even if callback delivery fails.

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]);

Dashboard and Retention

Human API orders appear with normal human website orders in the customer dashboard. Transcriptions can be opened in the editor; captions can be downloaded from the project.

Errors

StatusMeaning
400Invalid media, missing idempotency key, invalid options, or an unsafe URL.
401Missing, invalid, or revoked API key.
402Insufficient Pay-As-You-Go Balance. No Human API order is created.
403The customer account is not active.
404The Human API job does not exist for this customer.
502The order was charged but could not be activated. Staff are notified; the balance is not automatically refunded.

Reference

Endpoint Purpose
POST /customerapi/human.php Submit one multipart file upload or JSON remote media URL for human transcription or captions.
GET /customerapi/human.php?job_id={job_id} Fetch job status and the inline TXT or SRT result after completion.