DocuTools API
Run every DocuTools tool from your own code. Same credits, same limits, files never stored.
Authentication
Create a key in Settings → API keys (your email must be verified), then send it with every request. Keys are shown once; keep them secret. You can revoke a key at any time.
Authorization: Bearer dt_your_api_key
Each successful job uses the tool's credit cost: daily plan credits first, then purchased credits. Failed jobs are free. API and website jobs share the same limit of 100 jobs per hour per account. Uploaded files are processed in memory and are not stored.
Run a tool
POST https://docutools.net/api/v1/tools/{slug} with multipart/form-data: one or more files fields plus the tool's options as text fields. The response body is the result file. The headers X-Credits-Charged and X-Credits-Left show what the job cost and what you have left.
curl -X POST https://docutools.net/api/v1/tools/merge-pdf \ -H "Authorization: Bearer $DOCUTOOLS_KEY" \ -F "files=@first.pdf" \ -F "files=@second.pdf" \ -o merged.pdf
import { readFile, writeFile } from 'node:fs/promises'
const form = new FormData()
form.append('files', new Blob([await readFile('report.pdf')]), 'report.pdf')
form.append('angle', '90')
const res = await fetch('https://docutools.net/api/v1/tools/rotate-pdf', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.DOCUTOOLS_KEY}` },
body: form,
})
if (!res.ok) throw new Error((await res.json()).error)
await writeFile('rotated.pdf', Buffer.from(await res.arrayBuffer()))
console.log('Credits left:', res.headers.get('X-Credits-Left'))import os, requests
res = requests.post(
"https://docutools.net/api/v1/tools/compress-image",
headers={"Authorization": f"Bearer {os.environ['DOCUTOOLS_KEY']}"},
files={"files": open("photo.jpg", "rb")},
data={"quality": "70"},
)
res.raise_for_status()
open("photo-small.jpg", "wb").write(res.content)Tools & options
jpg-to-pdfFiles: One or more JPG/PNG/WebP images (max 20), combined in the order sent.
merge-pdfFiles: Two or more PDFs (max 20), merged in the order sent.
split-pdfFiles: One PDF.
pages(required) — Page numbers or ranges, e.g. "1-3,5". The pages to keep in the new PDF.
delete-pagesFiles: One PDF.
pages(required) — Page numbers or ranges, e.g. "1-3,5". The pages to remove.
rotate-pdfFiles: One PDF.
angle— Rotation in degrees: 90, 180 or 270. Default 90.pages— Page numbers or ranges, e.g. "1-3,5". Default: all pages.
page-numbersFiles: One PDF.
start— First page number. Default 1.position— "bottom-center" (default) or "bottom-right".
watermark-pdfFiles: One PDF.
text(required) — Watermark text, up to 40 basic characters.opacity— Opacity in percent, 5–80. Default 20.
compress-imageFiles: One JPG/PNG/WebP image.
quality— Quality 30–95. Default 70.
resize-imageFiles: One JPG/PNG/WebP image.
width— Width in pixels (1–8000). Send width, height or both.height— Height in pixels (1–8000).
convert-imageFiles: One image.
format— Output format: "jpg", "png" (default) or "webp".
image-to-sizeFiles: One JPG/PNG/WebP image.
kb(required) — Maximum file size in KB (10–10000). The result is at or below this size.format— Output format: "jpg" (default) or "webp".
verify-stampFiles: One PDF. Requires a verified email. The response has an X-Stamp-Code header; the file can be checked at /verify.
pages— "all" (default), "first" or "last".position— "bottom-left" (default) or "bottom-right".
bulk-certificatesFiles: One certificate template PDF (up to 5 pages); the name is printed on the first page. Requires a verified email. Costs the tool price per name. Returns a ZIP with one PDF per name and manifest.csv (number, name, file, code, verify_url).
names(required) — Recipient names, one per line (max 200, 80 characters each). Latin letters, accents allowed.top— Vertical position of the name, in percent from the top of the first page (5–95). Default 50.size— Font size in points (10–96). Long names shrink to fit. Default 36.font— "serif" (default), "italic" or "sans".color— "black" (default), "navy", "maroon" or "gold".position— QR stamp position: "bottom-left" (default) or "bottom-right".
batch-stampFiles: Up to 20 PDFs. Requires a verified email. Costs the tool price per file. Returns a ZIP with the stamped PDFs and manifest.csv (file, code, verify_url); the X-Stamp-Count header has the number of codes.
pages— "all" (default), "first" or "last".position— "bottom-left" (default) or "bottom-right".
proof-of-existenceFiles: One file of any type. Requires a verified email. The file is not changed or stored; its SHA-256 fingerprint is registered. Returns a PDF certificate; the X-Stamp-Code header has the code.
Workflows
POST https://docutools.net/api/v1/workflow runs 2–6 tools in a row in one request. Send the input files plus a steps field with JSON; each step's result becomes the next step's input. The job costs the sum of the steps and counts as one job for the hourly limit. Credits are only used if every step succeeds. verify-stamp can only be the last step.
curl -X POST https://docutools.net/api/v1/workflow \
-H "Authorization: Bearer $DOCUTOOLS_KEY" \
-F "files=@part-1.pdf" -F "files=@part-2.pdf" \
-F 'steps=[{"tool":"merge-pdf"},{"tool":"page-numbers","options":{"position":"bottom-right"}},{"tool":"verify-stamp","options":{"pages":"last"}}]' \
-o contract.pdf -D headers.txtStamped results include an X-Stamp-Code header. Anyone can check the file at docutools.net/verify; only its fingerprint is compared, the file is not uploaded.
Account & tool list
GET https://docutools.net/api/v1/credits returns your available credits and the next daily reset.
{
"total": 113,
"daily": { "left": 63, "allowance": 100, "resetsAt": "2026-10-25T17:00:00.000Z" },
"purchased": 50,
"plan": { "name": "Standard", "interval": "month", "activeUntil": "2026-11-25T09:00:00.000Z" }
}GET https://docutools.net/api/v1/tools lists the active tools with their slug, credit cost and options.
GET https://docutools.net/api/v1/status needs no key and returns operational, degraded or down with response times. Human-readable version: /status.
Status codes
Errors return JSON like { "error": "…" }. No credits are used when a request fails.
| 400 | The upload could not be read. Send multipart/form-data with the files in the "files" field. |
| 401 | Missing, malformed, invalid or revoked API key. |
| 402 | Not enough credits. Wait for the daily reset (00:00 WIB) or buy a credit pack. |
| 403 | The account is disabled or its email address is not verified. |
| 404 | Unknown or inactive tool. |
| 413 | A file is larger than 10 MB, or the job is larger than 30 MB in total. |
| 422 | The tool could not process the input (for example invalid page ranges). No credits were used. |
| 429 | Rate limit reached: 100 jobs per hour per account, or too many failed key attempts. |
Questions or need higher limits? Contact support.