# `server` Start the pdftl API server ## Usage > pdftl `server` `[port=]` `[host=]` `[replace]` `[max_upload_mb=]` `[timeout=]` ## Details Starts a stateless pdftl API server. Exposes all pdftl operations over HTTP. Syntax: `server [port=] [host=] [replace] [max_upload_mb=] [timeout=]` Arguments: * `port`: Port number to listen on (default: 4080). * `host`: Host address to bind to (default: 127.0.0.1). * [`replace`](): Shutdown an existing active server on this port before binding. * `max_upload_mb`: Maximum accepted request body size, in megabytes (default: 100). Requests whose `Content-Length` exceeds this are rejected with HTTP 413 before the body is read. Raise this if you routinely process very large PDFs. * `timeout`: Maximum wall-clock seconds allowed for a single operation or pipeline request to run before it is abandoned with HTTP 504 (default: 300). The operation runs in an isolated child process; if the timeout is exceeded, that process is forcibly terminated (SIGTERM, escalating to SIGKILL if needed), so this bounds both response latency and actual CPU/memory usage of a runaway operation. ## Authentication By default the server has **no authentication on any endpoint** -- this is intentional for local/trusted-network use. The one exception is binding to a non-loopback `host` (anything other than `127.0.0.1`, `localhost`, or `::1`, including `0.0.0.0`): in that case, `PDFTL_SERVER_SHUTDOWN_TOKEN` **must** be set in the environment before starting the server, or it refuses to bind at all. This exists solely to stop an unauthenticated `/v1/shutdown` from being reachable from the network; it does not gate any other endpoint. ``` export PDFTL_SERVER_SHUTDOWN_TOKEN="$(openssl rand -hex 32)" pdftl server host=0.0.0.0 port=4080 ``` Include the token on shutdown requests: ``` curl -X POST http://your-host:4080/v1/shutdown \ -H "X-Shutdown-Token: $PDFTL_SERVER_SHUTDOWN_TOKEN" ``` `server replace` also forwards this token automatically (read from the same environment variable) when shutting down the instance it's replacing. ## Calling the server from cURL We outline how to interact with the stateless `pdftl` HTTP server directly using standard `curl` commands. Of course, other clients can be used. The daemon by default binds to: * **Base URL:** `http://127.0.0.1:4080` ### 1. System Operations #### Query Daemon Status and Registry To retrieve active server information, version metadata, and a dynamically reflected list of supported operations: ``` curl -X GET http://127.0.0.1:4080/v1/status ``` #### Shutdown the Server To cleanly terminate the loopback socket listener administratively: ``` curl -X POST http://127.0.0.1:4080/v1/shutdown ``` If a shutdown token is configured (mandatory for non-loopback binds, see above), include it: ``` curl -X POST http://127.0.0.1:4080/v1/shutdown \ -H "X-Shutdown-Token: $PDFTL_SERVER_SHUTDOWN_TOKEN" ``` ### 2. Document Processing Operations All execution endpoints follow the format: `POST /v1/execute/{operation}`. Payloads are submitted as `multipart/form-data`. #### A. Zero-Input Operations (e.g., [`create`]()) Operations like [`create`]() generate a new document from scratch and do not require uploading a seed PDF. Pass configuration strings in the [`args`](<../general/args.md>) field: ``` curl -X POST http://127.0.0.1:4080/v1/execute/create \ -F "args=[\"1(A4)\"]" \ --output blank_page.pdf ``` #### B. Single-Input Operations (e.g., [`crop`]()) To send an existing PDF file to be processed, pass the document in the `file` parameter. You can submit parameters via a JSON array in the [`args`](<../general/args.md>) field: ``` curl -X POST http://127.0.0.1:4080/v1/execute/crop \ -F "file=@input.pdf" \ -F "args=[\"10pt,20pt\"]" \ --output cropped.pdf ``` > **Tip:** If the operation returns a modified PDF, write it directly to a file using `--output` or stream it. #### C. Multi-Input Operations (e.g., [`cat`]()) The server dynamically translates named form-data parts (e.g. `A`, `B`) into operational handle aliases. This allows you to upload multiple files at once and reference them in your sequence arguments: ``` curl -X POST http://127.0.0.1:4080/v1/execute/cat \ -F "A=@first.pdf" \ -F "B=@second.pdf" \ -F "args=[\"A\", \"B\"]" \ --output merged.pdf ``` ##### Selective Page Splicing You can also reference page-specific slices inside your handles: ``` curl -X POST http://127.0.0.1:4080/v1/execute/cat \ -F "A=@first.pdf" \ -F "B=@second.pdf" \ -F "args=[\"A1-3\", \"B2-end\"]" \ --output spliced.pdf ``` #### D. JSON Extraction Operations (e.g., [`dump_data`]()) For operations that return structural text or JSON payloads instead of a PDF file, the server responds with raw text/JSON containing metadata content: ``` curl -X POST http://127.0.0.1:4080/v1/execute/dump_data \ -F "file=@input.pdf" \ -F "args=[\"json\"]" ``` #### E. Pipelines (multiple operations in one request) To chain several operations together server-side — without downloading and re-uploading an intermediate file — POST to `/v1/execute/pipeline` instead of a single operation name. The [`args`](<../general/args.md>) field becomes a JSON array of step objects, each naming an `operation` and its own [`args`](<../general/args.md>): ``` curl -X POST http://127.0.0.1:4080/v1/execute/pipeline \ -F "A=@first.pdf" \ -F "B=@second.pdf" \ -F 'args=[{"operation": "cat", "args": ["A", "B"]}, {"operation": "rotate", "args": ["left"]}]' \ --output merged_rotated.pdf ``` Uploaded file handles (`A`, `B`, ...) are visible to every step, matching the handle behaviour of the CLI pipeline. Each step after the first implicitly receives the previous step's output, unless it specifies its own `inputs` list of handle names. The final step may include an `options` object to control output encryption, e.g. `{"operation": "rotate", "args": ["right"], "options": {"owner_pw": "secret", "encrypt_aes256": true}}`. ### 3. Limits Requests exceeding `max_upload_mb` receive HTTP 413. Requests whose operation runs longer than `timeout` seconds receive HTTP 504. ## Examples > Start the server on default localhost:4080. ``` pdftl server ``` > Shutdown any active server on port 8080, then start binding to all interfaces. Requires PDFTL_SERVER_SHUTDOWN_TOKEN to be set in the environment, since host is non-loopback. ``` pdftl server port=8080 host=0.0.0.0 replace ``` > Start on default localhost:4080 with higher upload/timeout limits. ``` pdftl server max_upload_mb=500 timeout=600 ``` **Tags**: server, utility *Source: pdftl.operations.server_op* *Read online: [https://pdftl.readthedocs.io/en/latest/operations/server.html](https://pdftl.readthedocs.io/en/latest/operations/server.html)* *Type: Operation*