YouTube transcript API for AI agents — pay per successful transcript via x402 (USDC on Base) or on the Apify Store.
The guarantee: you are charged only when a transcript is delivered. No captions, private/deleted video, or a failure on our side → HTTP error → no charge.
Base URL: https://transcriptd.fly.dev
| Endpoint | Price | Returns |
|---|---|---|
GET /transcript?video={url|id}&format={json|text|srt}&lang=en |
$0.005 | caption segments with timestamps + cleaned text |
GET /metadata?video={url|id} |
$0.002 | title, channel, duration, available caption languages |
GET / , GET /healthz |
free | service doc / health + extractor version |
No API key, no account, no subscription — payment IS the authentication (x402, USDC on Base, gasless for the payer).
# pip install "x402[httpx,evm]" eth-account
from eth_account import Account
from x402 import x402Client
from x402.http.clients import x402_httpx_transport
from x402.mechanisms.evm import EthAccountSigner
from x402.mechanisms.evm.exact import ExactEvmScheme
import httpx, asyncio
async def main():
xc = x402Client()
xc.register("eip155:*", ExactEvmScheme(signer=EthAccountSigner(
Account.from_key("0x<key holding USDC on Base>"))))
async with httpx.AsyncClient(transport=x402_httpx_transport(xc),
base_url="https://transcriptd.fly.dev") as c:
r = await c.get("/transcript", params={"video": "dQw4w9WgXcQ", "format": "text"})
print(r.text)
asyncio.run(main())Thin wrapper in mcp/server.py — tools get_transcript and
get_video_metadata. Your wallet key stays in YOUR client config; it never
leaves your machine.
{
"mcpServers": {
"transcriptd": {
"command": "python",
"args": ["mcp/server.py"],
"env": { "X402_PRIVATE_KEY": "0x<key holding USDC on Base>" }
}
}
}Same engine, Apify billing, residential proxy included: apify.com/outspoken_sitkaspruce/transcriptd — input a list of video URLs, get a dataset of transcripts, charged per delivered transcript only.
- Captions only (manual preferred, auto-generated fallback) — no ASR.
- Extractor auto-updates daily; timedtext rate limits are retried with backoff.
- JSON output:
{video_id, language, source, segments: [{start, dur, text}], text}.