API documentation
Every tool can be called over HTTP from your own programs – the same processing as on the website, on our servers in Germany.
Machine-readable as an OpenAPI file: /api/v1/openapi.json
Quickstart
From zero to your first call in three steps.
Create a test key
Sign in (free, only an email code) and create a key in your account under “API keys”. Choose a test key: it is free, limited to 20 calls per day and files up to 5 MB.
Store the key
Keep the key in an environment variable instead of in your code:
export OWT_KEY=owk_test_...Build and run your call
Choose a tool below, copy the call and run it. The result is the processed file (or, for check tools, a JSON report).
Call builder
Pick a tool and its options and copy a ready call in curl, JavaScript, Python or PHP. Everything happens in your browser; nothing is sent.
curl -X POST 'https://wandlix.com/api/v1/tools/merge-pdf' \
-H "Authorization: Bearer $OWT_KEY" \
-F 'files=@file1.pdf' \
-F 'files=@file2.pdf' \
-OJThe examples read your key from the environment variable OWT_KEY. Never put a key into code that you publish.
Access
Create an API key in your account and send it in the Authorization header with every request. Go to your account
Authorization: Bearer owk_YOUR_KEYAn invalid or revoked key is rejected (HTTP 401) – never treated as a guest. Keep keys out of public code, browser programs and repositories.
Test keys
Keys starting with owk_test_ are free and never touch your balance. They are meant for trying out your integration and are limited to 20 calls per day and files up to 5 MB. After that you get HTTP 402 (quota_exceeded).
In your account you can set your own limit of requests per minute for each key; it then replaces the per-IP limit.
Request
One request per job, as multipart/form-data. Files stay in memory only and are discarded after the response.
POST https://wandlix.com/api/v1/tools/<tool>
Content-Type: multipart/form-datafiles– one or more files; the order is the processing orderoptions– optional, JSON text with the tool’s options (see the table below)
Tools that take no files (for example qr-code and create-einvoice) also accept Content-Type: application/json with the body {"options": {…}}. That helps with clients that cannot send form uploads, such as online curl services.
curl
curl -X POST "https://wandlix.com/api/v1/tools/merge-pdf" \
-H "Authorization: Bearer $OWT_KEY" \
-F "files=@a.pdf" -F "files=@b.pdf" \
-o merged.pdfcurl -X POST "https://wandlix.com/api/v1/tools/compress-image" \
-H "Authorization: Bearer $OWT_KEY" \
-F "files=@photo.png" \
-F 'options={"quality":70,"maxWidth":1600}' \
-o photo-small.pngJavaScript (Node.js)
const form = new FormData();
form.append("files", new Blob([await fs.readFile("a.pdf")]), "a.pdf");
form.append("files", new Blob([await fs.readFile("b.pdf")]), "b.pdf");
const res = await fetch("https://wandlix.com/api/v1/tools/merge-pdf", {
method: "POST",
headers: { Authorization: "Bearer " + process.env.OWT_KEY },
body: form,
});
if (!res.ok) throw new Error((await res.json()).error);
await fs.writeFile("merged.pdf", Buffer.from(await res.arrayBuffer()));Python
import os, requests
res = requests.post(
"https://wandlix.com/api/v1/tools/merge-pdf",
headers={"Authorization": "Bearer " + os.environ["OWT_KEY"]},
files=[("files", open("a.pdf", "rb")), ("files", open("b.pdf", "rb"))],
)
res.raise_for_status()
open("merged.pdf", "wb").write(res.content)PHP
$ch = curl_init("https://wandlix.com/api/v1/tools/merge-pdf");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("OWT_KEY")],
CURLOPT_POSTFIELDS => [
"files[0]" => new CURLFile("a.pdf"),
"files[1]" => new CURLFile("b.pdf"),
],
CURLOPT_RETURNTRANSFER => true,
]);
file_put_contents("merged.pdf", curl_exec($ch));Response
On success (HTTP 200) you get the result file, or a ZIP when there are several result files. The file name is in the Content-Disposition header, extra details in the X-Result-Info header (URL-encoded JSON).
The e-invoice check returns JSON with the check report under result instead.
Tools and options
The tool identifier goes into the URL. Options you leave out use their default.
| Tool | Files / size | File types | Options |
|---|---|---|---|
validate-einvoiceValidate e-invoice | 1–20, ≤ 50 MB | pdf, xml | – |
create-einvoiceCreate e-invoice (XRechnung) | 0, ≤ 1 MB | pdf, xml | JSON text (seller, buyer, invoice, payment, lines); no files. Returns the XML and the check report. |
merge-pdfMerge PDF | 2–20, ≤ 50 MB | – | |
split-pdfSplit PDF | 1, ≤ 50 MB |
| |
pdf-to-imagePDF to image | 1, ≤ 50 MB |
| |
compress-pdfCompress PDF | 1, ≤ 50 MB |
| |
ocr-pdfMake PDF searchable (OCR) | 1, ≤ 50 MB |
| |
protect-pdfProtect PDF | 1, ≤ 50 MB |
| |
unlock-pdfUnlock PDF | 1, ≤ 50 MB |
| |
delete-pdf-pagesDelete PDF pages | 1, ≤ 50 MB |
| |
rotate-pdfRotate PDF | 1, ≤ 50 MB |
| |
watermark-pdfAdd watermark to PDF | 1, ≤ 50 MB |
| |
add-page-numbersAdd page numbers to PDF | 1, ≤ 50 MB |
| |
reorder-pdfReorder PDF pages | 1, ≤ 50 MB |
| |
crop-pdfCrop PDF | 1, ≤ 50 MB |
| |
pdf-to-pdfaPDF to PDF/A | 1–10, ≤ 50 MB | pdf, doc, docx, odt, rtf, xls, xlsx, ods, ppt, pptx, odp |
|
pdf-to-textPDF to text / Markdown | 1, ≤ 50 MB |
| |
remove-metadataRemove metadata | 1–20, ≤ 50 MB | pdf, jpg, jpeg, png, webp | – |
images-to-pdfImages to PDF | 1–50, ≤ 50 MB | jpg, jpeg, png, webp, gif, tif, tiff, avif, svg |
|
ocr-imageImage to text (OCR) | 1–10, ≤ 50 MB | jpg, jpeg, png, webp, gif, tif, tiff, avif, svg |
|
convert-imageConvert image | 1–20, ≤ 50 MB | jpg, jpeg, png, webp, gif, tif, tiff, avif, svg |
|
compress-imageCompress image | 1–20, ≤ 50 MB | jpg, jpeg, png, webp |
|
edit-imageEdit image | 1–20, ≤ 50 MB | jpg, jpeg, png, webp, gif, tif, tiff, avif, svg |
|
word-to-pdfWord to PDF | 1–5, ≤ 50 MB | docx, doc, odt, rtf, pages | – |
excel-to-pdfExcel to PDF | 1–5, ≤ 50 MB | xlsx, xls, ods, csv, numbers | – |
powerpoint-to-pdfPowerPoint to PDF | 1–5, ≤ 50 MB | pptx, ppt, odp, key | – |
numbers-to-excelNumbers to Excel | 1–5, ≤ 50 MB | numbers | – |
convert-officeDocument converter (DOCX, ODT, XLSX, ODS …) | 1–5, ≤ 50 MB | docx, doc, odt, rtf, xlsx, xls, ods, pptx, ppt, odp |
|
pdf-to-wordPDF to Word | 1–3, ≤ 50 MB |
| |
text-to-pdfText to PDF | 1–10, ≤ 50 MB | txt, md, log |
|
extract-einvoice-xmlExtract XML from ZUGFeRD PDF | 1–10, ≤ 50 MB | – | |
einvoice-to-pdfE-invoice to PDF | 1–10, ≤ 50 MB | pdf, xml |
|
csv-to-excelCSV to Excel | 1–10, ≤ 50 MB | csv, tsv, txt |
|
excel-to-csvExcel to CSV | 1–10, ≤ 50 MB | xlsx, xls, ods |
|
zip-filesCreate ZIP file | 1–50, ≤ 50 MB | * | – |
unzip-filesUnzip files | 1, ≤ 50 MB | zip | – |
qr-codeQR code generator | 0, ≤ 1 MB | * | JSON text, no files: "type" (text, url, wifi, email, phone, sms, vcard, geo, event, sepa, whatsapp) with the fields of that type, plus format (png, svg, pdf), size, ecc, margin, fg, bg, transparent, style. Returns the image. |
convert-dataJSON, CSV, XML, YAML converter | 1–10, ≤ 20 MB | json, csv, tsv, xml, yaml, yml, txt |
|
convert-encodingConvert text encoding | 1–20, ≤ 20 MB | * |
|
base64Base64 encode and decode | 1–10, ≤ 50 MB | * |
|
Usage and limits
Every call is charged to your account – just like on the website.
- Your account’s daily free quota applies first.
- After that credits are deducted (the month’s free credits first, then purchased ones). The cost per tool is shown in your account.
- Failed calls cost nothing.
- At most 15 requests per minute per IP address; beyond that you get HTTP 429.
Errors
Errors come as JSON with an error field and the matching HTTP status.
HTTP 402
{"error":"quota_exceeded"}| HTTP | error | Meaning |
|---|---|---|
| 400 | too_few | Too few files for this tool. |
| 400 | too_many | Too many files. |
| 415 | bad_type | File type or request format not allowed. |
| 400 | bad_options | Invalid options. |
| 409 | conflict | Conflict with the current state. |
| 413 | too_large | The files are too large. |
| 422 | too_many_pages | The PDF has more pages than allowed for this tool. |
| 422 | encrypted | The file is password-protected. |
| 422 | wrong_password | Wrong password for the PDF. |
| 422 | invalid | The file is damaged or unreadable. |
| 503 | busy | The server is busy. Try again later. |
| 422 | infected | The virus scan found malware. |
| 422 | no_einvoice | No e-invoice found in the file. |
| 422 | no_text | The PDF contains no extractable text (for example a scan). |
| 402 | quota_exceeded | Quota and balance are used up. |
| 429 | rate_limited | Too many requests. Wait a moment. |
| 401 | login_required | Sign-in required. |
| 401 | invalid_key | The API key is invalid or revoked. |
| 400 | bad_url | Not a valid web address. |
| 422 | blocked_url | The address is not allowed (block list). |
| 400 | bad_alias | Invalid custom name. |
| 409 | alias_taken | Custom name already taken. |
| 503 | unavailable | The tool is temporarily unavailable. Try again later. |
| 500 | server | Internal error. |
Privacy
The API works exactly like the website: processing in Germany, files in memory only, deleted after an hour at the latest, no logging of file names or contents.