PDF Compression API
Shrink PDF files with one POST request via Ghostscript's own recompression — pick a quality level, optionally convert to grayscale, and never get back a file bigger than what you uploaded.
curl -X POST \ .../api/v1/convert.php \ -H "Authorization: Bearer ..." \ -F "category=document-compress" \ -F "level=high" \ -F "file=@report.pdf" \ -o output.pdf
https://transconvert.com/api/v1/convert.php
Parameter
| Field | Description |
|---|---|
Authorization | Required. "Bearer tc_live_...". |
category | Set to "document-compress". |
level | Optional: "low", "medium" (default), "high", or "none". |
grayscale | Optional. "1" to also convert to grayscale; omit for full color. |
file | Required. A PDF that is not open/password-protected. |
Contoh
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 output.pdf
<?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' => 'document-compress', 'level' => 'high', 'file' => new CURLFile('report.pdf'), ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($status === 200) { file_put_contents('output.pdf', $response); } else { $error = json_decode($response, true); echo $error['error']['message']; }
const form = new FormData(); form.append('category', 'document-compress'); form.append('level', 'high'); form.append('file', new Blob([fs.readFileSync('report.pdf')]), 'report.pdf'); 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('output.pdf', Buffer.from(await res.arrayBuffer())); } else { const { error } = await res.json(); console.error(error.message); }
import requests with open('report.pdf', 'rb') as f: response = requests.post( 'https://transconvert.com/api/v1/convert.php', headers={'Authorization': 'Bearer tc_live_your_key_here'}, data={'category': 'document-compress', 'level': 'high'}, files={'file': f}, ) if response.status_code == 200: with open('output.pdf', '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('report.pdf') do |file| req = Net::HTTP::Post::Multipart.new url, 'category' => 'document-compress', 'level' => 'high', 'file' => UploadIO.new(file, 'application/octet-stream', 'report.pdf') 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('output.pdf', 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", "document-compress") .addFormDataPart("level", "high") .addFormDataPart("file", "report.pdf", RequestBody.create(new File("report.pdf"), MediaType.parse("application/octet-stream"))) .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("output.pdf"), response.body().bytes()); } else { System.err.println(response.body().string()); } }
Respons
Jika berhasil (200): byte mentah file hasil konversi, dengan header Content-Type dan Content-Disposition yang sesuai. Jika gagal: isi JSON berbentuk {"error": {"code": "...", "message": "..."}} dengan kode status HTTP yang sesuai — lihat bagian Kesalahan di bawah.
| Header | Value |
|---|---|
Content-Type | Tipe MIME sebenarnya dari file hasil konversi (mis. image/png, application/pdf). |
Content-Disposition | attachment; filename="..." — nama file yang disarankan, sama seperti unduhan file pada umumnya. |
Content-Length | Ukuran isi respons dalam byte. |
X-Original-Size | Ukuran file yang diunggah dalam byte, sebelum kompresi. |
X-Saved-Percent | Perkiraan seberapa lebih kecil hasilnya dibandingkan file asli, dalam persentase bilangan bulat (bisa 0). |
Setiap kesalahan mengikuti bentuk JSON yang sama, misalnya ketika kuota terlampaui:
{
"error": {
"code": "quota_exceeded",
"message": "Monthly API allowance of 5000 conversion-minutes reached.",
"limit": 5000,
"used": 5000
}
}
Kesalahan
Setiap kegagalan mengembalikan bungkus kesalahan JSON berisi "code" yang dapat digunakan kode Anda untuk pencabangan logika, ditambah "message" yang mudah dibaca manusia. Beberapa kesalahan menyertakan kolom tambahan (misalnya, quota_exceeded menyertakan "limit" dan "used").
| Status & code | When it happens |
|---|---|
401 missing_key | Header Authorization tidak dikirim. |
401 invalid_key | Kunci tidak ada, atau sudah dicabut. |
403 account_suspended | Akun pemilik kunci ini telah ditangguhkan. |
403 plan_required | Akun berada di paket Gratis — akses API memerlukan paket Basic, Lite, Pro, atau Tim. |
400 invalid_category | "category" bukan "image" atau "document". |
400 no_file | Tidak ada file yang dikirim, atau unggahan gagal — kolom harus diberi nama "file". |
413 file_too_large | Ukuran file melebihi batas unggah maksimum paket Anda. |
429 quota_exceeded | Jatah menit konversi bulanan paket Anda telah habis. Akan diatur ulang di awal bulan kalender berikutnya. |
429 concurrency_limit | Terlalu banyak konversi yang berjalan bersamaan untuk akun ini (dibagi dengan situs web) — tunggu salah satunya selesai lalu coba lagi. |
422 conversion_failed | File itu sendiri tidak dapat dikonversi — "message" menjelaskan alasannya. Kode status bervariasi tergantung alasannya: 400/415/422 berarti file atau target tidak akan pernah berhasil sebanyak apa pun Anda mencoba ulang; 500/503 berarti ada masalah di sisi server, dan khusus 503 layak dicoba ulang sebentar lagi. |