Bỏ qua, tới nội dung
Tài liệu APIv1

O3O DocBuilder và chuyển đổi

Chuyển đổi định dạng

POST /v1/convert đổi một tệp sang định dạng khác trong cùng họ tài liệu (văn bản, bảng tính, trình chiếu), kể cả PDF, PDF/A và ảnh PNG hoặc JPG của một trang; chạy đồng bộ hoặc bất đồng bộ, nguồn tải lên hoặc lấy từ URL.

Trong trang này

Gửi một tệp nguồn, nhận lại tệp đích. Nguồn gửi theo một trong hai cách: tải tệp lên bằng multipart/form-data (trường file), hoặc gửi application/jsonurl để DocBuilder tự tải về. Chỉ chuyển trong cùng một họ tài liệu; khác họ, ví dụ docx sang xlsx, trả 415 unsupported_format.

POST/v1/convert

Chuyển đổi định dạng. Đồng bộ trả thẳng tệp; bất đồng bộ trả job.

Xác thực: BearerCộng đồngDoanh nghiệp

Tham số#

Thân multipart/form-data

  • filefilebắt buộc
    Tệp nguồn.
  • tostringbắt buộc
    Định dạng đích: docx, odt, rtf, txt, html, pdf, xlsx, ods, csv, pptx, odp, png, jpg.
  • fromstringtuỳ chọn
    Định dạng nguồn: docx, doc, odt, rtf, txt, html, xlsx, xls, ods, csv, pptx, ppt, odp. Không có thì lấy theo đuôi tên tệp.
  • filenamestringtuỳ chọnMặc định: tên nguồn đổi đuôi
    Tên tệp kết quả, tối đa 255 ký tự.
  • optionsstring (JSON)tuỳ chọn
    Tuỳ chọn chuyển đổi, gửi dạng CHUỖI JSON (xem bảng dưới).
  • asyncbooleantuỳ chọnMặc định: false
    true: trả ngay 202 kèm job thay vì chờ tệp.
  • callback_urlstring (URL)tuỳ chọn
    Chỉ bản doanh nghiệp có tính năng callback. Nhận POST khi job xong hoặc lỗi.

Thân application/json

  • urlstring (URL)bắt buộc
    URL tải tệp nguồn, tối đa 2048 ký tự, chịu quy tắc chống SSRF.
  • tostringbắt buộc
    Định dạng đích: docx, odt, rtf, txt, html, pdf, xlsx, ods, csv, pptx, odp, png, jpg.
  • fromstringtuỳ chọn
    Định dạng nguồn: docx, doc, odt, rtf, txt, html, xlsx, xls, ods, csv, pptx, ppt, odp. Không có thì lấy theo đuôi tên tệp.
  • filenamestringtuỳ chọnMặc định: tên nguồn đổi đuôi
    Tên tệp kết quả, tối đa 255 ký tự.
  • optionsobjecttuỳ chọn
    Tuỳ chọn chuyển đổi (xem bảng dưới).
  • asyncbooleantuỳ chọnMặc định: false
    true: trả ngay 202 kèm job thay vì chờ tệp.
  • callback_urlstring (URL)tuỳ chọn
    Chỉ bản doanh nghiệp có tính năng callback. Nhận POST khi job xong hoặc lỗi.

Đối tượng options

  • passwordstringtuỳ chọn
    Mật khẩu MỞ tệp nguồn. Thiếu hoặc sai: 422 password_required.
  • pdf.pdfabooleantuỳ chọnMặc định: false
    Xuất PDF/A-2b để lưu trữ lâu dài.
  • pdf.page_rangestringtuỳ chọnMặc định: mọi trang
    Khoảng trang, ví dụ 1-3,5. Mẫu: ^[0-9]+(-[0-9]+)?(,[0-9]+(-[0-9]+)?)*$.
  • pdf.image_qualityinteger 1–100tuỳ chọnMặc định: 90
    Chất lượng ảnh bên trong PDF.
  • image.pageinteger ≥ 1tuỳ chọnMặc định: 1
    Trang được xuất khi đích là png hoặc jpg.
  • image.widthinteger 16–4000tuỳ chọnMặc định: 1240
    Chiều rộng ảnh, điểm ảnh; chiều cao theo tỷ lệ trang.
  • csv.delimiterstring, 1 ký tựtuỳ chọnMặc định: ,
    Ký tự phân tách cột.
  • csv.encodingutf-8 | windows-1258 | windows-1252tuỳ chọnMặc định: utf-8
    Bảng mã của tệp CSV.
  • csv.sheetinteger ≥ 1tuỳ chọnMặc định: 1
    Trang tính được xuất khi đích là csv.

Chuyển đổi đồng bộ#

Mặc định (async = false) DocBuilder giữ kết nối tới khi xong và trả thẳng tệp kết quả với mã 200. Quá sync_timeout_seconds (60 giây ở cả hai gói) thì trả 504 timeout; tệp lớn hoặc nhiều trang nên dùng chế độ bất đồng bộ. Mã tệp trong header X-O3O-File-Id tải lại được ở GET /v1/files/{id} tới khi hết thời gian giữ.

Đổi docx sang PDF
curl -sS http://localhost:8080/v1/convert \
  -H "Authorization: Bearer O3O_DEMO_KEY" \
  -F "file=@bao-cao.docx" \
  -F "to=pdf" \
  -o bao-cao.pdf -w "HTTP %{http_code}\n"
import { readFile, writeFile } from "node:fs/promises";

const BASE_URL = "http://localhost:8080";
const HEADERS = { Authorization: "Bearer O3O_DEMO_KEY" };

const form = new FormData();
form.append("file", new Blob([await readFile("bao-cao.docx")]), "bao-cao.docx");
form.append("to", "pdf");

const res = await fetch(`${BASE_URL}/v1/convert`, {
  method: "POST",
  headers: HEADERS,
  body: form,
  signal: AbortSignal.timeout(90_000),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
await writeFile("bao-cao.pdf", Buffer.from(await res.arrayBuffer()));
import requests

BASE_URL = "http://localhost:8080"
HEADERS = {"Authorization": "Bearer O3O_DEMO_KEY"}

with open("bao-cao.docx", "rb") as f:
    r = requests.post(
        f"{BASE_URL}/v1/convert",
        headers=HEADERS,
        files={"file": ("bao-cao.docx", f)},
        data={
            "to": "pdf",
        },
        timeout=90,
    )
if not r.ok:
    raise RuntimeError(f"{r.status_code}: {r.text}")
with open("bao-cao.pdf", "wb") as fh:
    fh.write(r.content)
<?php
$ch = curl_init("http://localhost:8080/v1/convert");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ["Authorization: Bearer O3O_DEMO_KEY"],
    CURLOPT_POSTFIELDS => [
        'file' => new CURLFile('bao-cao.docx'),
        'to' => 'pdf',
    ],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 90,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($body === false || $status >= 400) {
    throw new RuntimeException("HTTP $status: " . ($body === false ? curl_error($ch) : $body));
}
file_put_contents("bao-cao.pdf", $body);
using System.Net.Http.Headers;

using var http = new HttpClient { Timeout = TimeSpan.FromSeconds(90) };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "O3O_DEMO_KEY");

using var form = new MultipartFormDataContent();
form.Add(new ByteArrayContent(await File.ReadAllBytesAsync("bao-cao.docx")), "file", "bao-cao.docx");
form.Add(new StringContent("pdf"), "to");

using var res = await http.PostAsync("http://localhost:8080/v1/convert", form);
if (!res.IsSuccessStatusCode)
    throw new HttpRequestException($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}");
await File.WriteAllBytesAsync("bao-cao.pdf", await res.Content.ReadAsByteArrayAsync());
200Chế độ đồng bộ: thân phản hồi là tệp nhị phân. Khối dưới đây liệt kê các header đi kèm (bản cộng đồng, nên có cả header theo ngày).
{
  "X-O3O-Request-Id": "req_0123456789abcdef",
  "X-O3O-Job-Id": "job_5f0c2a9e41b7d3c8a6e1f024",
  "X-O3O-File-Id": "file_9b3e7d21c4a8f0e65d1b2c37",
  "Content-Disposition": "attachment; filename=\"bao-cao.pdf\"",
  "X-RateLimit-Limit": "10",
  "X-RateLimit-Remaining": "9",
  "X-RateLimit-Reset": "1789984860",
  "X-RateLimit-Limit-Day": "200",
  "X-RateLimit-Remaining-Day": "187"
}

Nguồn từ URL#

Gửi application/json với url. DocBuilder tự tải tệp theo quy tắc chống SSRF: chỉ httphttps, không có phần user:pass@, tối đa 2048 ký tự; mọi địa chỉ mà tên miền phân giải ra phải là địa chỉ công cộng, và DocBuilder nối thẳng tới đúng địa chỉ IP đã kiểm, không phân giải lại (chống DNS rebinding); tự xử lý tối đa 3 lần chuyển hướng và kiểm lại từng chặng; chỉ mã 200 là thành công; thời gian tải tối đa theo O3O_FETCH_TIMEOUT_SECONDS (mặc định 30 giây).

Đổi tệp từ URL sang PDF/A
curl -sS http://localhost:8080/v1/convert \
  -H "Authorization: Bearer O3O_DEMO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/files/bao-cao.docx", "to": "pdf", "options": {"pdf": {"pdfa": true}}}' \
  -o bao-cao.pdf -w "HTTP %{http_code}\n"
import { writeFile } from "node:fs/promises";

const BASE_URL = "http://localhost:8080";
const HEADERS = { Authorization: "Bearer O3O_DEMO_KEY" };

const payload = {
  "url": "https://example.com/files/bao-cao.docx",
  "to": "pdf",
  "options": {
    "pdf": {
      "pdfa": true
    }
  }
};

const res = await fetch(`${BASE_URL}/v1/convert`, {
  method: "POST",
  headers: { ...HEADERS, "Content-Type": "application/json" },
  body: JSON.stringify(payload),
  signal: AbortSignal.timeout(90_000),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
await writeFile("bao-cao.pdf", Buffer.from(await res.arrayBuffer()));
import requests

BASE_URL = "http://localhost:8080"
HEADERS = {"Authorization": "Bearer O3O_DEMO_KEY"}

payload = {
    "url": "https://example.com/files/bao-cao.docx",
    "to": "pdf",
    "options": {
        "pdf": {
            "pdfa": True
        }
    }
}
r = requests.post(f"{BASE_URL}/v1/convert", headers=HEADERS, json=payload, timeout=90)
if not r.ok:
    raise RuntimeError(f"{r.status_code}: {r.text}")
with open("bao-cao.pdf", "wb") as fh:
    fh.write(r.content)
<?php
$payload = json_encode([
    'url' => 'https://example.com/files/bao-cao.docx',
    'to' => 'pdf',
    'options' => ['pdf' => ['pdfa' => true]],
], JSON_UNESCAPED_UNICODE);

$ch = curl_init("http://localhost:8080/v1/convert");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ["Authorization: Bearer O3O_DEMO_KEY", "Content-Type: application/json"],
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 90,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($body === false || $status >= 400) {
    throw new RuntimeException("HTTP $status: " . ($body === false ? curl_error($ch) : $body));
}
file_put_contents("bao-cao.pdf", $body);
using System.Net.Http.Headers;
using System.Text;

using var http = new HttpClient { Timeout = TimeSpan.FromSeconds(90) };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "O3O_DEMO_KEY");

var json = """
    {
      "url": "https://example.com/files/bao-cao.docx",
      "to": "pdf",
      "options": {
        "pdf": {
          "pdfa": true
        }
      }
    }
    """;
using var res = await http.PostAsync("http://localhost:8080/v1/convert",
    new StringContent(json, Encoding.UTF8, "application/json"));
if (!res.IsSuccessStatusCode)
    throw new HttpRequestException($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}");
await File.WriteAllBytesAsync("bao-cao.pdf", await res.Content.ReadAsByteArrayAsync());

Chuyển đổi bất đồng bộ#

Đặt async = true để nhận ngay 202 kèm đối tượng job và header Location: /v1/jobs/{id}. Sau đó hỏi trạng thái và tải tệp như ở trang Việc bất đồng bộ. Cả hai gói đều dùng được chế độ này; riêng callback_url chỉ có ở bản doanh nghiệp có tính năng callback, bản cộng đồng gửi tham số này nhận 403 forbidden_feature.

Gửi job chuyển đổi
curl -sS http://localhost:8080/v1/convert \
  -H "Authorization: Bearer O3O_DEMO_KEY" \
  -F "file=@bao-cao.docx" \
  -F "to=pdf" \
  -F "async=true"
import { readFile } from "node:fs/promises";

const BASE_URL = "http://localhost:8080";
const HEADERS = { Authorization: "Bearer O3O_DEMO_KEY" };

const form = new FormData();
form.append("file", new Blob([await readFile("bao-cao.docx")]), "bao-cao.docx");
form.append("to", "pdf");
form.append("async", "true");

const res = await fetch(`${BASE_URL}/v1/convert`, {
  method: "POST",
  headers: HEADERS,
  body: form,
  signal: AbortSignal.timeout(90_000),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
console.log(await res.json());
import requests

BASE_URL = "http://localhost:8080"
HEADERS = {"Authorization": "Bearer O3O_DEMO_KEY"}

with open("bao-cao.docx", "rb") as f:
    r = requests.post(
        f"{BASE_URL}/v1/convert",
        headers=HEADERS,
        files={"file": ("bao-cao.docx", f)},
        data={
            "to": "pdf",
            "async": "true",
        },
        timeout=90,
    )
if not r.ok:
    raise RuntimeError(f"{r.status_code}: {r.text}")
print(r.json())
<?php
$ch = curl_init("http://localhost:8080/v1/convert");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ["Authorization: Bearer O3O_DEMO_KEY"],
    CURLOPT_POSTFIELDS => [
        'file' => new CURLFile('bao-cao.docx'),
        'to' => 'pdf',
        'async' => 'true',
    ],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 90,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($body === false || $status >= 400) {
    throw new RuntimeException("HTTP $status: " . ($body === false ? curl_error($ch) : $body));
}
print_r(json_decode($body, true));
using System.Net.Http.Headers;

using var http = new HttpClient { Timeout = TimeSpan.FromSeconds(90) };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "O3O_DEMO_KEY");

using var form = new MultipartFormDataContent();
form.Add(new ByteArrayContent(await File.ReadAllBytesAsync("bao-cao.docx")), "file", "bao-cao.docx");
form.Add(new StringContent("pdf"), "to");
form.Add(new StringContent("true"), "async");

using var res = await http.PostAsync("http://localhost:8080/v1/convert", form);
if (!res.IsSuccessStatusCode)
    throw new HttpRequestException($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}");
Console.WriteLine(await res.Content.ReadAsStringAsync());
202Job đã vào hàng đợi. Header Location trỏ tới /v1/jobs/{id}.
{
  "id": "job_5f0c2a9e41b7d3c8a6e1f024",
  "kind": "convert",
  "status": "queued",
  "created_at": "2026-09-21T10:00:00Z",
  "started_at": null,
  "finished_at": null,
  "duration_ms": null,
  "expires_at": null,
  "outputs": [],
  "error": null,
  "callback": null
}

Tuỳ chọn PDF#

  • pdf.pdfa = true xuất PDF/A-2b, phù hợp lưu trữ hồ sơ dài hạn.
  • pdf.page_range chọn trang, ví dụ 1-3,5 là trang 1 tới 3 và trang 5.
  • pdf.image_quality từ 1 tới 100 (mặc định 90): số nhỏ cho tệp nhẹ hơn, ảnh kém nét hơn.
Trang 1 tới 3 và trang 5, PDF/A, ảnh chất lượng 80
curl -sS http://localhost:8080/v1/convert \
  -H "Authorization: Bearer O3O_DEMO_KEY" \
  -F "file=@bao-cao.docx" \
  -F "to=pdf" \
  --form-string 'options={"pdf":{"pdfa":true,"page_range":"1-3,5","image_quality":80}}' \
  -o bao-cao-trich.pdf -w "HTTP %{http_code}\n"
import json

import requests

BASE_URL = "http://localhost:8080"
HEADERS = {"Authorization": "Bearer O3O_DEMO_KEY"}

with open("bao-cao.docx", "rb") as f:
    r = requests.post(
        f"{BASE_URL}/v1/convert",
        headers=HEADERS,
        files={"file": ("bao-cao.docx", f)},
        data={
            "to": "pdf",
            "options": json.dumps({"pdf": {"pdfa": True, "page_range": "1-3,5", "image_quality": 80}}, ensure_ascii=False),
        },
        timeout=90,
    )
if not r.ok:
    raise RuntimeError(f"{r.status_code}: {r.text}")
with open("bao-cao-trich.pdf", "wb") as fh:
    fh.write(r.content)
import { readFile, writeFile } from "node:fs/promises";

const BASE_URL = "http://localhost:8080";
const HEADERS = { Authorization: "Bearer O3O_DEMO_KEY" };

const form = new FormData();
form.append("file", new Blob([await readFile("bao-cao.docx")]), "bao-cao.docx");
form.append("to", "pdf");
form.append("options", JSON.stringify({"pdf": {"pdfa": true, "page_range": "1-3,5", "image_quality": 80}}));

const res = await fetch(`${BASE_URL}/v1/convert`, {
  method: "POST",
  headers: HEADERS,
  body: form,
  signal: AbortSignal.timeout(90_000),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
await writeFile("bao-cao-trich.pdf", Buffer.from(await res.arrayBuffer()));
Sắp có

PDF có mật khẩu (đặt mật khẩu cho tệp PDF xuất ra). Hiện options.password chỉ dùng để mở tệp nguồn có mật khẩu.

Xuất ảnh một trang#

Đích png hoặc jpg xuất đúng một trang mỗi lần gọi, chọn bằng options.image.page (mặc định trang 1), rộng options.image.width điểm ảnh (16 tới 4000, mặc định 1240), chiều cao theo tỷ lệ trang. Ảnh đi qua PDF trung gian rồi dựng bằng pdftoppm, nên chọn được trang bất kỳ ở cả văn bản, bảng tính và trình chiếu. Chỉ cần ảnh thu nhỏ thì dùng POST /v1/extract/thumbnail.

Trang chiếu số 2 thành PNG rộng 1600 điểm ảnh
curl -sS http://localhost:8080/v1/convert \
  -H "Authorization: Bearer O3O_DEMO_KEY" \
  -F "file=@gioi-thieu.pptx" \
  -F "to=png" \
  --form-string 'options={"image":{"page":2,"width":1600}}' \
  -o trang-2.png -w "HTTP %{http_code}\n"
import json

import requests

BASE_URL = "http://localhost:8080"
HEADERS = {"Authorization": "Bearer O3O_DEMO_KEY"}

with open("gioi-thieu.pptx", "rb") as f:
    r = requests.post(
        f"{BASE_URL}/v1/convert",
        headers=HEADERS,
        files={"file": ("gioi-thieu.pptx", f)},
        data={
            "to": "png",
            "options": json.dumps({"image": {"page": 2, "width": 1600}}, ensure_ascii=False),
        },
        timeout=90,
    )
if not r.ok:
    raise RuntimeError(f"{r.status_code}: {r.text}")
with open("trang-2.png", "wb") as fh:
    fh.write(r.content)
import { readFile, writeFile } from "node:fs/promises";

const BASE_URL = "http://localhost:8080";
const HEADERS = { Authorization: "Bearer O3O_DEMO_KEY" };

const form = new FormData();
form.append("file", new Blob([await readFile("gioi-thieu.pptx")]), "gioi-thieu.pptx");
form.append("to", "png");
form.append("options", JSON.stringify({"image": {"page": 2, "width": 1600}}));

const res = await fetch(`${BASE_URL}/v1/convert`, {
  method: "POST",
  headers: HEADERS,
  body: form,
  signal: AbortSignal.timeout(90_000),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
await writeFile("trang-2.png", Buffer.from(await res.arrayBuffer()));

CSV#

Tuỳ chọn options.csv áp khi nguồn hoặc đích là csv: delimiter là một ký tự (mặc định dấu phẩy), encodingutf-8, windows-1258 hoặc windows-1252, còn sheet chọn trang tính được xuất khi đích là csv (mặc định trang 1). Tệp CSV xuất từ Excel trên máy đặt vùng Việt Nam có thể dùng dấu chấm phẩy và bảng mã windows-1258; khi đó đặt hai tuỳ chọn này cho khớp.

Trang tính thứ 2 ra CSV phân tách bằng dấu chấm phẩy
curl -sS http://localhost:8080/v1/convert \
  -H "Authorization: Bearer O3O_DEMO_KEY" \
  -F "file=@bang-luong.xlsx" \
  -F "to=csv" \
  --form-string 'options={"csv":{"delimiter":";","sheet":2}}' \
  -o theo-phong-ban.csv -w "HTTP %{http_code}\n"
import json

import requests

BASE_URL = "http://localhost:8080"
HEADERS = {"Authorization": "Bearer O3O_DEMO_KEY"}

with open("bang-luong.xlsx", "rb") as f:
    r = requests.post(
        f"{BASE_URL}/v1/convert",
        headers=HEADERS,
        files={"file": ("bang-luong.xlsx", f)},
        data={
            "to": "csv",
            "options": json.dumps({"csv": {"delimiter": ";", "sheet": 2}}, ensure_ascii=False),
        },
        timeout=90,
    )
if not r.ok:
    raise RuntimeError(f"{r.status_code}: {r.text}")
with open("theo-phong-ban.csv", "wb") as fh:
    fh.write(r.content)
CSV bảng mã Windows-1258 sang xlsx
curl -sS http://localhost:8080/v1/convert \
  -H "Authorization: Bearer O3O_DEMO_KEY" \
  -F "file=@du-lieu.csv" \
  -F "to=xlsx" \
  --form-string 'options={"csv":{"delimiter":";","encoding":"windows-1258"}}' \
  -o du-lieu.xlsx -w "HTTP %{http_code}\n"
import json

import requests

BASE_URL = "http://localhost:8080"
HEADERS = {"Authorization": "Bearer O3O_DEMO_KEY"}

with open("du-lieu.csv", "rb") as f:
    r = requests.post(
        f"{BASE_URL}/v1/convert",
        headers=HEADERS,
        files={"file": ("du-lieu.csv", f)},
        data={
            "to": "xlsx",
            "options": json.dumps({"csv": {"delimiter": ";", "encoding": "windows-1258"}}, ensure_ascii=False),
        },
        timeout=90,
    )
if not r.ok:
    raise RuntimeError(f"{r.status_code}: {r.text}")
with open("du-lieu.xlsx", "wb") as fh:
    fh.write(r.content)

Định dạng hỗ trợ#

HọNguồnĐích
textdocx, doc, odt, rtf, txt, htmldocx, odt, rtf, txt, html, pdf, png, jpg
sheetxlsx, xls, ods, csvxlsx, ods, csv, html, pdf, png, jpg
slidepptx, ppt, odppptx, odp, pdf, png, jpg

Ma trận chi tiết, cách DocBuilder nhận biết định dạng nguồn và danh sách font có sẵn: xem Ma trận định dạng.

Gói và giới hạn#

Cả hai gói đều dùng được endpoint này. Các giới hạn liên quan:

Hạng mụcBản cộng đồngBản doanh nghiệp
Cỡ tệp vào hoặc ra tối đa (max_file_mb)10 MB300 MB
Thời gian chờ tối đa của chế độ đồng bộ (sync_timeout_seconds)60 giây60 giây
Thời gian chạy tối đa của một job (job_timeout_seconds)120 giây600 giây
Chế độ bất đồng bộ (async)
Callback khi job xong (callback)khôngcó, khi token có tính năng callback

Mã lỗi thường gặp#

HTTPKhi nào
400bad_requestThiếu tham số, JSON hỏng, options sai kiểu, thiếu cả file lẫn url. detail.errors = [{path, message}].
401unauthorizedThiếu hoặc sai khoá. detail.reasonmissing, invalid hoặc no_keys_configured.
403forbidden_featureGửi callback_url khi đang ở bản cộng đồng.
413file_too_largeTệp vào hoặc tệp ra vượt max_file_mb. detail.limit_mb.
415unsupported_formatKhông nhận ra định dạng nguồn, hoặc đổi khác họ (ví dụ docx sang xlsx).
422corrupt_sourceLibreOffice không mở được tệp nguồn.
422password_requiredTệp có mật khẩu mà không truyền mật khẩu, hoặc mật khẩu sai.
422url_not_allowedURL vi phạm quy tắc chống SSRF.
422download_failedKhông tải được URL nguồn.
429rate_limitedVượt hạn mức. detail.windowminute hoặc day; kèm Retry-After.
503queue_fullHàng đợi đã đầy (max_queued_jobs); kèm Retry-After.
504timeoutChế độ đồng bộ quá sync_timeout_seconds, hoặc job quá job_timeout_seconds. Worker bị dừng và dựng lại.
422Tệp nguồn có mật khẩu mà không gửi options.password.
{
  "error": {
    "code": "password_required",
    "message": "Tệp có mật khẩu. Hãy gửi mật khẩu mở tệp trong options.password.",
    "detail": {},
    "request_id": "req_0123456789abcdef"
  }
}
429Vượt hạn mức theo phút; chờ số giây trong Retry-After.
{
  "error": {
    "code": "rate_limited",
    "message": "Đã vượt hạn mức yêu cầu trong phút này.",
    "detail": {
      "window": "minute"
    },
    "request_id": "req_0123456789abcdef"
  }
}