curl -X POST \ .../api/v1/convert.php \ -H "Authorization: Bearer ..." \ -F "category=image" \ -F "target=PNG" \ -F "file=@photo.jpg" \ -o converted.png
快速上手
三个步骤,从零开始完成您的第一次文件转换。
注册(或将现有账户升级)至 Basic、Lite、Pro 或 Team 套餐,然后在账户页面生成一个密钥——您可以随时返回查看它。
将文件以 multipart/form-data 的形式 POST 到下方接口,在 Authorization 请求头中携带您的密钥,并设置 category 和 target。
返回 200 表示响应体即为转换后文件的原始字节——直接保存响应体即可。其他状态码则表示 JSON 格式的错误信息,说明出错原因。
身份验证
每个请求都需要一个 API 密钥,在 Authorization 请求头中以 Bearer token 的形式发送。
Authorization: Bearer tc_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
适用于 Basic、Lite、Pro 和 Team 套餐。 在您的账户中生成密钥 →
测试您的密钥
在编写正式的接入代码之前,快速确认密钥是否可用——这个请求本身不会转换任何文件(未附带文件),但如果返回 400 no_file 而不是 401,就说明密钥本身是有效的。
curl -X POST -H "Authorization: Bearer tc_live_your_key_here" -F "category=image" https://transconvert.com/api/v1/convert.php
接口
单个接口即可处理所有转换。请发送包含文件及以下字段的 multipart/form-data POST 请求。
https://transconvert.com/api/v1/convert.php
参数
| Field | Description |
|---|---|
Authorization | 必填。"Bearer tc_live_..."。 |
category | 必填。"image" 或 "document"——如需压缩而非转换,请参见下方的 Compress。 |
target | 必填。输出格式代码,例如 "PNG"、"DOCX"——请参见下方的支持的格式。 |
file | 必填。要转换的文件(multipart 上传)。 |
pdf_mode | 可选,仅适用于 image 类别。"pages"(默认,将每一页栅格化)或 "extract"(按原样提取嵌入的图片)——仅当源文件为 PDF 时有效。 |
pdf_pages | 可选,仅适用于 image 类别。"all"(默认)或 "first"。 |
pdf_quality | 可选,仅适用于 image 类别。"normal"(默认,150 DPI)或 "high"(300 DPI)。 |
常见转换
常用格式组合速查——同一个接口即可处理所有这些转换,只需使用不同的 category/target 组合。
| Source → target | category | target |
|---|---|---|
| PNG → JPG | image | JPG |
| JPG → PNG | image | PNG |
| HEIC → JPG | image | JPG |
| WEBP → PNG | image | PNG |
| JPG → PDF | image | PDF |
| PDF → JPG | image | JPG |
| DOCX → PDF | document | PDF |
| PDF → DOCX | document | DOCX |
| PPTX → PDF | document | PDF |
| XLSX → PDF | document | PDF |
响应
成功时(200):返回转换后文件的原始字节,并设置相应的 Content-Type 和 Content-Disposition 响应头。失败时:返回如 {"error": {"code": "...", "message": "..."}} 结构的 JSON,并附带相应的 HTTP 状态码——请参见下方的错误说明。
| Header | Value |
|---|---|
Content-Type | 转换后文件的实际 MIME 类型(例如 image/png、application/pdf)。 |
Content-Disposition | attachment; filename="..."——建议的文件名,与普通文件下载相同。 |
Content-Length | 响应体的大小(字节)。 |
压缩
在不改变格式的前提下缩小文件——输入和输出格式相同。压缩使用与转换不同的一组独立类别,image-compress 和 document-compress,各自的可选参数如下。
image-compress
输入和输出格式相同(JPG/PNG/WEBP/GIF)——target_percent 表示希望结果相对于原文件缩小到的大致比例,而非固定的质量设置。
| Field | Description |
|---|---|
category | 设置为 "image-compress"。 |
target_percent | 可选,1–100(默认 60)。目标大小占原文件的大致百分比——数值越小,压缩程度越高。 |
file | 必填。JPG、PNG、WEBP 或 GIF。 |
curl -X POST \ https://transconvert.com/api/v1/convert.php \ -H "Authorization: Bearer tc_live_your_key_here" \ -F "category=image-compress" \ -F "target_percent=50" \ -F "file=@photo.jpg" \ -o compressed.jpg
document-compress
输入和输出均为 PDF,通过 Ghostscript 自身的重新压缩实现——返回的文件绝不会比上传的文件更大(如果重新压缩没有效果,则回退为原文件)。
| Field | Description |
|---|---|
category | 设置为 "document-compress"。 |
level | 可选:"low"、"medium"(默认)、"high" 或 "none"。压缩程度越高,视觉质量的损失越大,主要影响嵌入的图片/扫描件。 |
grayscale | 可选。设为 "1" 可同时转换为灰度;不填则保留全彩。 |
file | 必填。未被打开或未设密码保护的 PDF(如果已加密,请先在网站上使用“解锁 PDF”)。 |
curl -X POST \ https://transconvert.com/api/v1/convert.php \ -H "Authorization: Bearer tc_live_your_key_here" \ -F "category=document-compress" \ -F "level=high" \ -F "file=@report.pdf" \ -o compressed.pdf
| Header | Value |
|---|---|
X-Original-Size | 上传文件在压缩前的大小(字节)。 |
X-Saved-Percent | 结果文件相对于原文件缩小的大致比例,以整数百分比表示(可以为 0)。 |
视频和音频(异步)
视频和音频转换可能需要数分钟才能完成,时间太长,无法用单次同步请求处理——因此这类转换使用“先提交、后轮询”的流程,而不是上方的接口。提交文件后会立即获得一个 job_id,随后轮询其状态直至完成。
提交任务
与主接口相同的 multipart POST 格式,只是使用不同的 URL。
https://transconvert.com/api/v1/convert-async.php
| Field | Description |
|---|---|
Authorization | 必填。"Bearer tc_live_..."。 |
category | "video" 或 "audio"。 |
target | 必填——例如 "MP4"、"MOV"、"MP3"、"WAV"。 |
file | 必填。要转换的文件(multipart 上传)。 |
webhook_url | 可选。任务完成后将结果通过 POST 发送到的 http(s) 地址,而不必只轮询 job-status.php。必须解析为公网地址。 |
curl -X POST \ https://transconvert.com/api/v1/convert-async.php \ -H "Authorization: Bearer tc_live_your_key_here" \ -F "category=video" \ -F "target=MP4" \ -F "file=@clip.mov"
响应(202 Accepted)
{ "job_id": "job_242e1555d78d166807aa56502f15d118", "status": "queued" }
轮询状态
使用返回的 job_id 每隔几秒轮询一次此接口。"status" 的取值为 queued、processing、completed 或 failed 之一。
https://transconvert.com/api/v1/job-status.php?job_id=job_...
{
"job_id": "job_242e1555d78d166807aa56502f15d118",
"status": "completed",
"category": "video",
"target_format": "MP4",
"created_at": "2026-08-26 19:17:47",
"download_url": "/api/v1/job-status.php?job_id=job_...&download=1",
"filename": "clip.mp4"
}
Webhook(可选)
如果您在提交时提供了 webhook_url,任务完成后(无论成功还是失败)我们会向该地址 POST 同样的 JSON 内容一次;如果您的端点无响应,会重试几次。无论如何,job-status.php 仍可作为备用方案使用。
POST your webhook_url { "job_id": "job_242e1555d78d166807aa56502f15d118", "status": "completed", "category": "video", "target_format": "MP4", "created_at": "2026-08-26 19:17:47", "download_url": "https://transconvert.com/api/v1/job-status.php?job_id=job_...&download=1", "filename": "clip.mp4" }
下载结果
当 status 变为 "completed" 后,响应中会包含 download_url——即在同一个状态查询 URL 后附加 &download=1。请求该地址会以原始字节流返回转换后的文件,响应头与本页其他接口一致。结果会在被下载的那一刻立即删除;如果从未被下载,则会在短暂的保留期后自动删除。
schedule任务结果会在下载后立即删除;如果从未被下载,则会在短暂的保留期后自动删除——请及时下载。
示例
同一个请求分别用四种语言实现——选择与您的技术栈匹配的即可。每个示例都会将本地的 photo.jpg 转换为 PNG 并保存结果。
curl -X POST \ https://transconvert.com/api/v1/convert.php \ -H "Authorization: Bearer tc_live_your_key_here" \ -F "category=image" \ -F "target=PNG" \ -F "file=@photo.jpg" \ -o converted.png
<?php $ch = curl_init('https://transconvert.com/api/v1/convert.php'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Authorization: Bearer tc_live_your_key_here'], CURLOPT_POSTFIELDS => [ 'category' => 'image', 'target' => 'PNG', 'file' => new CURLFile('photo.jpg'), ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($status === 200) { file_put_contents('converted.png', $response); } else { $error = json_decode($response, true); echo $error['error']['message']; }
const form = new FormData(); form.append('category', 'image'); form.append('target', 'PNG'); form.append('file', new Blob([fs.readFileSync('photo.jpg')]), 'photo.jpg'); const res = await fetch('https://transconvert.com/api/v1/convert.php', { method: 'POST', headers: { Authorization: 'Bearer tc_live_your_key_here' }, body: form, }); if (res.ok) { fs.writeFileSync('converted.png', Buffer.from(await res.arrayBuffer())); } else { const { error } = await res.json(); console.error(error.message); }
import requests with open('photo.jpg', 'rb') as f: response = requests.post( 'https://transconvert.com/api/v1/convert.php', headers={'Authorization': 'Bearer tc_live_your_key_here'}, data={'category': 'image', 'target': 'PNG'}, files={'file': f}, ) if response.status_code == 200: with open('converted.png', 'wb') as out: out.write(response.content) else: print(response.json()['error']['message'])
# gem install multipart-post require 'net/http' require 'net/http/post/multipart' url = URI('https://transconvert.com/api/v1/convert.php') File.open('photo.jpg') do |file| req = Net::HTTP::Post::Multipart.new url, 'category' => 'image', 'target' => 'PNG', 'file' => UploadIO.new(file, 'image/jpeg', 'photo.jpg') req['Authorization'] = 'Bearer tc_live_your_key_here' res = Net::HTTP.start(url.host, url.port, use_ssl: true) do |http| http.request(req) end if res.code == '200' File.write('converted.png', res.body) else puts JSON.parse(res.body)['error']['message'] end end
// Gradle: implementation("com.squareup.okhttp3:okhttp:4.+") OkHttpClient client = new OkHttpClient(); RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("category", "image") .addFormDataPart("target", "PNG") .addFormDataPart("file", "photo.jpg", RequestBody.create(new File("photo.jpg"), MediaType.parse("image/jpeg"))) .build(); Request request = new Request.Builder() .url("https://transconvert.com/api/v1/convert.php") .header("Authorization", "Bearer tc_live_your_key_here") .post(body) .build(); try (Response response = client.newCall(request).execute()) { if (response.isSuccessful()) { Files.write(Paths.get("converted.png"), response.body().bytes()); } else { System.err.println(response.body().string()); } }
错误
每个失败请求都会返回一个 JSON 错误信息,其中包含可供代码判断分支的 "code",以及便于阅读的 "message"。部分错误还包含额外字段(例如 quota_exceeded 会包含 "limit" 和 "used")。
{
"error": {
"code": "quota_exceeded",
"message": "Monthly API allowance of 5000 conversion-minutes reached.",
"limit": 5000,
"used": 5000
}
}
| Status & code | When it happens |
|---|---|
401 missing_key | 未发送 Authorization 请求头。 |
401 invalid_key | 密钥不存在,或已被撤销。 |
403 account_suspended | 拥有此密钥的账户已被暂停。 |
403 plan_required | 该账户为 Free 套餐——API 访问权限需要 Basic、Lite、Pro 或 Team 套餐。 |
400 invalid_category | "category" 既不是 "image" 也不是 "document"。 |
400 missing_target | "target" 为空。 |
400 no_file | 未发送文件,或上传失败——字段名必须为 "file"。 |
413 file_too_large | 文件大小超出您所在套餐的最大上传限制。 |
429 quota_exceeded | 该套餐每月的转换分钟数已用完,将于下个自然月初重置。 |
429 concurrency_limit | 此账户同时运行的转换任务过多(与网站共用限额)——请等待其中一个完成后重试。 |
400/415/422/500/503 conversion_failed | 文件本身无法转换——"message" 中会说明原因。状态码会因原因而异:400/415/422 表示无论重试多少次,该文件或目标格式都无法成功;500/503 表示服务器端出现问题,其中 503 值得进行一次短暂重试。 |
405 method_not_allowed | HTTP 方法错误——此接口仅接受 POST 请求。 |
400 invalid_target | "target" 不是该类别支持的输出格式。 |
404 job_not_found | 该账户下不存在此 id 对应的任务(对其他账户的 job_id 同样会返回此错误——不会泄露其是否存在)。 |
410 result_gone | 任务已完成,但其结果已被删除(结果会在下载后立即删除,或在从未下载的情况下于短暂保留期后自动删除)。 |
500 storage_failed | 服务器未能保存上传的文件以供后台处理。可以安全重试。 |
处理错误与重试
请根据 JSON 中的 "code" 字段进行分支处理,而不是 "message" 文本——文案可能会随时间变化,但 code 不会。concurrency_limit 值得在几秒后进行一次短暂重试(一旦您正在进行的某个转换完成,该限制就会解除);quota_exceeded 在下个月之前不会自行恢复,因此不要在循环中反复重试。conversion_failed 是唯一一个 HTTP 状态码仍然重要的错误码:503 是临时性的服务器端问题,值得进行一次短暂重试,而 400/415/422/500 则表示无论重发多少次,该文件/目标格式的组合都不会成功。在上传前于客户端检查文件大小,可以避免发送一个必然会返回 file_too_large 的请求。
套餐与限制
API 与您在网站上使用的套餐共享相同的限额——无需另行配置。
Basic
bolt2000 转换分钟数 / 月
upload_file文件大小上限 2 GB
sync_alt同时 50 个请求
speed30 次请求/分钟
Lite
bolt3000 转换分钟数 / 月
upload_file文件大小上限 4 GB
sync_alt同时 100 个请求
speed60 次请求/分钟
Pro
bolt5000 转换分钟数 / 月
upload_file文件大小上限 10 GB
sync_alt同时请求数不限
speed120 次请求/分钟
Team
bolt10000 转换分钟数 / 月
upload_file文件大小上限 20 GB
sync_alt同时请求数不限
speed240 次请求/分钟
toll如果团队使用月度共享额度池,则与之共享
一旦适用每分钟限制,每个响应都会包含 X-RateLimit-Limit 和 X-RateLimit-Remaining 响应头;429 响应还会包含 Retry-After(单位:秒)——请据此提前降低请求频率,而不是仅在收到 429 后才做出反应。
支持的格式
与网站完全相同的转换引擎——没有仅限 API 或仅限网站的功能。
可作为源格式:
JPG, PNG, GIF, WEBP, BMP, AVIF, PDF, PSD, TIFF, EPS, HEIC
可作为目标格式:
JPG, PNG, GIF, WEBP, BMP, AVIF, PDF, ICO, PSD, TIFF, EPS
可作为源格式:
PDF, DOCX, DOC, PPTX, PPT, XLSX, XLS, RTF, ODT, ODP, ODS, HTML
可作为目标格式:
PDF, DOCX, DOC, PPTX, PPT, XLSX, XLS, RTF, ODT, ODP, ODS
可同时作为源格式和目标格式(输入输出格式相同):
JPG, PNG, WEBP, GIF
可同时作为源格式和目标格式(输入输出格式相同):
可同时作为源格式和目标格式(输入输出格式相同):
MP4, MOV, AVI, MKV, WEBM
可同时作为源格式和目标格式(输入输出格式相同):
MP3, WAV, OGG, AAC, FLAC, M4A, WMA, OPUS, AIFF, AMR, AU, CAF, AC3, DTS, GSM, IRCAM, MP2, TTA, VOC, W64, WV, SPX, RM
info视频和音频的转换与压缩目前仅在网站上提供:同步 HTTP 请求并不适合可能耗时数分钟的任务。
常见问题
目前还不支持——这类转换可能需要数分钟,不太适合单次同步 HTTP 请求。这些转换目前仅在网站上提供;如果未来推出基于异步/任务的 API 版本,可能会加入 API 支持。
API 访问权限需要 Basic、Lite、Pro 或 Team 套餐。如果账户变为 Free 套餐——无论是主动取消还是订阅到期——现有密钥会立即停止工作。一旦账户恢复到付费套餐,密钥会自动重新生效,您无需重新生成新密钥。
在每个自然月的月初重置,而不是按您的账单日期重置。
目前没有——每个请求都会计入您实际的每月额度。接入调试期间建议使用小文件,以节省额度。
可以,但不能超过您所在套餐的并发限制(见上方的“套餐与限制”)——该限制与您同时在网站上进行的转换共用,并非单独的 API 专属额度。
对于 document-compress,是的——返回的 PDF 绝不会比上传的文件更大;如果 Ghostscript 的重新压缩没有效果,您会得到未经改动的原文件(X-Saved-Percent 将显示为 0)。对于 image-compress,target_percent 只是编码器尝试达到的目标,并非硬性保证——如果原文件本身已经高度压缩,可能无法进一步明显缩小。
准备好开始了吗?
生成一个密钥,一分钟内即可完成您的第一次请求。
获取您的 API 密钥