PHP调用Fathom API语音转写需用Bearer Token认证(从控制台获取,勿混淆)、POST /v1/transcriptions上传原始音频(multipart/form-data + CURLFile)、轮询GET结果、手动处理说话人分离与词增强。

PHP调用Fathom API做语音转写要先搞清认证方式
Fathom不提供PHP SDK,所有请求都走REST API,认证靠Authorization Header传Bearer Token——不是API Key,也不是Basic Auth。Token得从Fathom控制台的Settings > API Access里手动创建,复制下来直接用,别误当成Webhook Secret或Client ID。
常见错误是把Token拼错成Bearer token123(少空格)或Bearer: token123(多冒号),结果返回401 Unauthorized;还有人拿前端JS SDK的临时token去后端调用,那肯定403。
- Token必须保存在环境变量里,比如
$_ENV['FATHOM_API_TOKEN'],绝不能硬编码进PHP文件 - 请求Header必须包含
Content-Type: application/json,否则Fathom直接拒收 - Fathom只接受
POST /v1/transcriptions,不支持GET或/recordings等路径
上传音频文件时PHP要用cURL发multipart/form-data
Fathom要求上传原始音频(MP3/WAV/FLAC),不能传URL,也不能传Base64字符串。PHP里最稳的方式是用cURL构造multipart/form-data,而不是用file_get_contents加JSON body——后者会触发415 Unsupported Media Type。
关键点在于CURLOPT_POSTFIELDS必须传数组,且音频字段名固定为audio,值用CURLFile封装(PHP 5.5+)。老版本PHP用@/path/to/file语法已废弃,会静默失败。
立即学习“PHP免费学习笔记(深入)”;
- 音频文件大小不能超100MB,超了Fathom返回
413 Payload Too Large - WAV文件务必是PCM格式,带压缩的WAV(如IMA ADPCM)会被转写成乱码
- 如果用
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true),反而会禁用CURLFile,导致上传为空
转写完成后取结果得轮询/v1/transcriptions/{id}
Fathom不支持Webhook回调,提交后立刻返回202 Accepted和一个id,但内容还没出来。必须自己定时GET这个ID对应的详情接口,直到status变成completed。别指望一次请求就拿到文本——99%的PHP新手在这卡住,以为API挂了。
轮询间隔建议2–3秒,最多试120次(约6分钟),超过说明音频有问题或Fathom服务延迟。响应体里真正要的是transcript.text字段,不是transcript.segments——后者是分段时间戳,纯文本转写用不到。
- GET请求也要带
AuthorizationHeader,和提交时一样 - 如果返回
status: failed,看error.message,常见是Invalid audio format或Audio too long - 别用
sleep()阻塞主线程,生产环境应改用队列(如Redis + worker)异步轮询
会议记录场景下需手动处理说话人分离与时间轴
Fathom默认不做说话人分离(Speaker Diarization),返回的transcript.text是一整段纯文字,没有“张三:”“李四:”前缀。如果会议录音含多人,得自己调/v1/transcriptions/{id}?include=segments,再按segments[].speaker字段拼接——但注意,这个字段只在提交时加"diarize": true才生效,且会延长处理时间。
另外,Fathom对中文会议常用词(如“钉钉”“飞书”“OKR”)识别不准,基本靠上下文猜。想提升准确率,只能提前在请求体里加word_boost数组,比如["OKR", "MVP", "SOP"],但单次最多 boost 10 个词,多了被忽略。
-
word_boost只影响识别概率,不保证一定出现,也不能填拼音或错别字 - 如果录音有背景音乐或多人重叠讲话,
diarize: true可能把同一人切分成多个speaker ID - Fathom不返回标点自动补全,句号逗号全靠模型推测,长句子容易断错



















