Use cases
What teams build with it. From one request.
- Analyze public page and creator videos
- Make Facebook video content searchable
- Repurpose reels and videos into text
- Feed video content into LLM pipelines
What you get
Transcripts in one schema. The same on every platform.
platformstring- Platform the media is hosted on.
idstring- Platform-native ID of the post (equals post.id).
urlstring- Canonical URL of the post.
languagestring- BCP-47 language of the returned transcript; null when unknown.
sourcestring- captions = platform caption track; asr = speech-to-text on the audio. New values may be added.
is_auto_generatedboolean- True when the track was machine-generated (platform auto-captions or ASR).
available_languagesstring[]- BCP-47 caption languages the platform offers for this post; [] if none or not listed.
duration_msinteger- Media duration in milliseconds; null when unknown.
Every field, its type and when it is null: the response reference and the transcript schema.
Example request
curl -G 'https://staging-fly.socialtap.dev/v1/facebook/transcript' \
--data-urlencode 'url=https://www.facebook.com/reel/1803909017420449/' \
-H "x-api-key: $SOCIALTAP_API_KEY"const params = new URLSearchParams({
url: "https://www.facebook.com/reel/1803909017420449/",
});
const res = await fetch(`https://staging-fly.socialtap.dev/v1/facebook/transcript?${params}`, {
headers: { "x-api-key": process.env.SOCIALTAP_API_KEY ?? "" },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
const { data, meta } = body;
console.log(data, meta.credits_charged);import os
import requests
res = requests.get(
"https://staging-fly.socialtap.dev/v1/facebook/transcript",
params={"url": "https://www.facebook.com/reel/1803909017420449/"},
headers={"x-api-key": os.environ["SOCIALTAP_API_KEY"]},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
data, meta = body["data"], body["meta"]
print(data, meta["credits_charged"])package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"os"
)
func main() {
q := url.Values{}
q.Set("url", "https://www.facebook.com/reel/1803909017420449/")
req, err := http.NewRequest("GET", "https://staging-fly.socialtap.dev/v1/facebook/transcript?"+q.Encode(), nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("x-api-key", os.Getenv("SOCIALTAP_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var body struct {
Data json.RawMessage `json:"data"`
Meta map[string]any `json:"meta"`
Error *struct {
Code string `json:"code"`
Message string `json:"message"`
} `json:"error"`
}
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
log.Fatal(err)
}
if body.Error != nil {
log.Fatalf("%s: %s", body.Error.Code, body.Error.Message)
}
fmt.Println(string(body.Data), body.Meta["credits_charged"])
}<?php
$query = http_build_query([
'url' => 'https://www.facebook.com/reel/1803909017420449/',
]);
$ch = curl_init('https://staging-fly.socialtap.dev/v1/facebook/transcript?' . $query);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['x-api-key: ' . getenv('SOCIALTAP_API_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
if (curl_getinfo($ch, CURLINFO_RESPONSE_CODE) >= 400) {
throw new RuntimeException($body['error']['code'] . ': ' . $body['error']['message']);
}
print_r($body['data']);
echo $body['meta']['credits_charged'], PHP_EOL;require "json"
require "net/http"
uri = URI("https://staging-fly.socialtap.dev/v1/facebook/transcript")
uri.query = URI.encode_www_form('url' => 'https://www.facebook.com/reel/1803909017420449/')
req = Net::HTTP::Get.new(uri)
req["x-api-key"] = ENV.fetch("SOCIALTAP_API_KEY")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") { |http| http.request(req) }
body = JSON.parse(res.body)
raise "#{body["error"]["code"]}: #{body["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
pp body["data"]
puts body["meta"]["credits_charged"]import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) throws Exception {
String query = "url=" + encode("https://www.facebook.com/reel/1803909017420449/");
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://staging-fly.socialtap.dev/v1/facebook/transcript?" + query))
.header("x-api-key", System.getenv("SOCIALTAP_API_KEY"))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
// An error is {"error": {"code", "message", ...}}; success is {data, meta}, meta.credits_charged its price.
if (response.statusCode() >= 400) throw new RuntimeException(response.body());
System.out.println(response.body());
}
static String encode(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8);
}
}using System.Text.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("x-api-key", Environment.GetEnvironmentVariable("SOCIALTAP_API_KEY"));
var query = string.Join("&",
"url=" + Uri.EscapeDataString("https://www.facebook.com/reel/1803909017420449/"));
var res = await http.GetAsync("https://staging-fly.socialtap.dev/v1/facebook/transcript?" + query);
using var body = JsonDocument.Parse(await res.Content.ReadAsStringAsync());
if (!res.IsSuccessStatusCode)
{
var error = body.RootElement.GetProperty("error");
throw new Exception($"{error.GetProperty("code")}: {error.GetProperty("message")}");
}
Console.WriteLine(body.RootElement.GetProperty("data"));
Console.WriteLine(body.RootElement.GetProperty("meta").GetProperty("credits_charged"));// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }, serde_json = "1"
use std::env;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let res = reqwest::blocking::Client::new()
.get("https://staging-fly.socialtap.dev/v1/facebook/transcript")
.query(&[("url", "https://www.facebook.com/reel/1803909017420449/")])
.header("x-api-key", env::var("SOCIALTAP_API_KEY")?)
.send()?;
let ok = res.status().is_success();
let body: serde_json::Value = res.json()?;
if !ok {
return Err(format!("{}: {}", body["error"]["code"], body["error"]["message"]).into());
}
println!("{} {}", body["data"], body["meta"]["credits_charged"]);
Ok(())
}{
"data": {
"available_languages": [
"en-US"
],
"duration_ms": 59861,
"id": "1803909017420449",
"is_auto_generated": false,
"language": "en-US",
"platform": "facebook",
"platform_specific": {},
"segments": [
{
"end_ms": 4000,
"start_ms": 33,
"text": "But the standard that we should continuously aspire to exceed,"
},
{
"end_ms": 7166,
"start_ms": 4000,
"text": "which is why we are bringing that intensity, that discipline, that"
},
{
"end_ms": 11400,
"start_ms": 7166,
"text": "engineering ownership back to NASA, because great nations do not remain great"
}
],
"source": "captions",
"text": "But the standard that we should continuously aspire to exceed, which is why we are bringing that intensity, that discipline, that engineering ownership back to NASA, because great nations do not remain great by being caretakers of history, but by continuously making history. We h…",
"url": "https://www.facebook.com/reel/1803909017420449/"
},
"meta": {
"request_id": "req_3f9c2a7d1e8b4c6a9f0e2d4b6a8c0e1f",
"platform": "facebook",
"source": "captions",
"is_cached": false,
"credits_charged": 1,
"latency_ms": 1517,
"fetched_at": "2026-10-25T12:00:00Z",
"input": {
"kind": "video",
"id": "1803909017420449",
"url": "https://www.facebook.com/reel/1803909017420449/"
},
"credits_remaining": 9999,
"client_request_id": null,
"warnings": [],
"mode": "live"
}
}Long arrays and strings are shortened for display; real responses are complete.
Reliability
Measured, not promised. Every request counts.
- p50 latency
- 1,517 ms
- p95 latency
- 2,437 ms
- Success rate
- 65.3%
- Requests measured
- 26
Staging measurements, not production. Measured on our staging environment, over the 7 days before 2026-10-25. How it is measured.
Pricing
Pay per request. Only when it succeeds.
| Source | Price per successful request | Per 1,000 requests |
|---|---|---|
Captions captions | 1 credit | $0.75–$1.45 |
Speech-to-text asr | 2 credits + 2 per started minute of media up to 122 credits (60 started minutes of media) | $1.50–$2.90 + $1.50–$2.90 per started minute of media |
- Failed requests are free: errors cost 0 credits.
- Cache hits are free: responses served from the cache cost 0 credits.
- Credits never expire.
- One credit balance for every endpoint and platform.
Credit packs · How this endpoint is priced · How credits work
FAQ