Appearance
XLS → XLSX
Converts a legacy Excel .xls workbook (the binary BIFF format) to a modern .xlsx. Every sheet is carried over, cell by cell.
| Slug | xls-to-xlsx |
| Sync | POST /v1/utilities/xls-to-xlsx → runXlsToXlsx |
| Async | POST /v1/utilities/xls-to-xlsx/jobs → createXlsToXlsxJob |
| Max duration | 300 s (5 min) |
| Output | one .xlsx file |
Quick example
bash
curl -X POST https://api.servicelabs.dev/v1/utilities/xls-to-xlsx \
-H "Authorization: Bearer $DU_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "input": { "url": "https://example.com/reports/report.xls" } }'js
const job = await fetch('https://api.servicelabs.dev/v1/utilities/xls-to-xlsx', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.DU_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ input: { url: 'https://example.com/reports/report.xls' } }),
}).then((r) => r.json())
console.log(job.status, job.result?.files[0].url)python
import os, requests
base = "https://api.servicelabs.dev"
h = {"Authorization": f"Bearer {os.environ['DU_API_KEY']}"}
job = requests.post(f"{base}/v1/utilities/xls-to-xlsx/jobs", headers=h,
json={"input": {"url": "https://example.com/reports/report.xls"}}).json()
while job["status"] not in ("succeeded", "failed", "cancelled"):
job = requests.get(f"{base}/v1/jobs/{job['id']}", params={"wait": 30}, headers=h).json()
print(job["result"]["files"][0]["url"] if job["result"] else job["error"])json
// → 200 OK (abridged)
{
"id": "job_01K7Z3Q4N5P6R7S8T9V0W1X2Y3",
"utility": "xls-to-xlsx",
"status": "succeeded",
"result": {
"files": [
{
"url": "https://files.servicelabs.dev/xls-to-xlsx/2026-09-10/job_01K7Z3Q4N5P6R7S8T9V0W1X2Y3/1789061409_report.xlsx",
"key": "xls-to-xlsx/2026-09-10/job_01K7Z3Q4N5P6R7S8T9V0W1X2Y3/1789061409_report.xlsx",
"name": "1789061409_report.xlsx",
"size": 20488,
"contentType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
}
]
}
}Input
| Field | Type | Required | Description |
|---|---|---|---|
url | string | yes | The .xls workbook. Must be http:// or https:// (no s3:// for this utility). |
Result
result.files holds exactly one file. Its name is <unix-seconds>_<source file name>.xlsx — the source's .xls extension becomes .xlsx (a source without an extension gets .xlsx appended). No extras.
Limits & behaviour
- Legacy
.xlsonly. The reader handles the binary BIFF format; a file that is already.xlsx(or a CSV renamed to.xls) is not a valid input and fails. - Values only. Cell values of every sheet are copied; formatting, formulas (their last computed values are kept), charts, macros and merged-cell styling are not.
- Source download times out after 30 s; the conversion itself has a 300 s ceiling. Typical workbooks take well under a second — the sync route is the natural fit.
Errors specific to this utility
| Situation | Outcome |
|---|---|
url missing or not http(s):// | 400 invalid_request — no job |
| Source can't be downloaded | failed job, 422 upstream_rejected (Failed to download file) |
Not a readable .xls workbook | failed job, 502 upstream_error (An error occurred during conversion: …) |
| Exceeded 300 s | failed job, 504 upstream_timeout |