Editing a PDF¶
Two ways to change a PDF:
- Server-side operations — send
optionstoPOST /convert/and let indox do the work (rotate, merge, watermark, redact, split, encrypt, OCR, …). - Save an edited file — you edited the PDF yourself and want indox to store
it and deliver it to a destination:
POST /save/.
Server-side operations¶
Add an options object to a normal conversion request. The input must be a PDF
and the output format is pdf unless the operation says otherwise. When
options is present, target_formats may be omitted — it defaults to pdf.
curl -X POST https://indox.org/api/v1/pdf_handler/convert/json/ \
-H "Authorization: Bearer $INDOX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"s3_key": "…/contract.pdf",
"target_formats": ["pdf"],
"options": {
"pages_delete": "2,4,6-9",
"watermark_text": "CONFIDENTIAL",
"watermark_opacity": 0.4,
"add_page_numbers": true
}
}'
The response, polling, and download are exactly the
standard conversion flow — 202, then poll
GET /conversion/{id}/.
On the multipart POST /convert/ endpoint, send options as a JSON string in
a form field of the same name.
Finding the available options¶
GET /operations/?input=pdf&output=pdf returns the full option list for the
running deployment — every option's name, type, default, description,
and, where the value is constrained, its possible_values. Read it rather than
hard-coding a list; the set grows.
A representative sample:
| Option | Type | Does |
|---|---|---|
pages_extract / pages_delete |
string | Keep or drop a page range, e.g. 1-3,5. |
reorganize_pages |
string | Reorder pages, e.g. 3,1,2. |
rotate_angle / rotate_pages |
number / string | Rotate by a multiple of 90°, all pages or a range. |
crop_left … crop_top |
number | Crop insets in points. |
additional_urls / additional_s3_keys |
array | Merge further PDFs into this one. |
watermark_text (+ size, colour, position, opacity, rotation) |
mixed | Stamp a text watermark; underlay puts it behind the content. |
add_page_numbers (+ position, font size, colour, margin) |
mixed | Number the pages. |
metadata |
object | Set Title, Author, and friends. |
form_fields / form_flatten |
object / boolean | Fill AcroForm fields, optionally making them read-only. |
decrypt_password |
string | Password needed to open an encrypted source PDF. |
encrypt_user_password / encrypt_owner_password |
string | Protect the output. |
change_permissions |
object | Set what the output allows (print, copy, annotate, …). |
auto_redact_terms |
array | Black out words or phrases. |
remove_annotations |
boolean | Strip comments, highlights, and markup. |
compress / ocr / repair / sanitize |
mixed | Shrink, OCR, repair, or strip active content. |
split_pages / split_by_size_or_count |
string / object | Split the document; the output is a ZIP. |
get_info / verify_pdf / compare |
boolean / object | Inspect a PDF; the output is a JSON report. |
Some options change the output type: splitting and image extraction produce a
ZIP, and the inspection options produce JSON. The outputs array on the status
response tells you what you actually got.
Not every option is available on every deployment — a few rely on an optional
PDF service. GET /operations/ only advertises the ones that are wired up.
Saving an edited PDF¶
POST /save/ accepts a finished PDF and delivers it to your chosen
destination. It is synchronous: there is nothing to poll.
curl -X POST https://indox.org/api/v1/pdf_handler/save/ \
-H "Authorization: Bearer $INDOX_TOKEN" \
-F "[email protected]" \
-F "filename=contract-signed.pdf" \
-F "destination=aws"
{
"id": "0a2b4c6d-8e01-4f23-9a45-b6c7d8e9f012",
"status": "completed",
"destination": "aws",
"download_url": "/api/v1/pdf_handler/0a2b…/download/",
"file_url": "https://…"
}
The status code is 201 Created.
| Field | Type | Notes |
|---|---|---|
file |
file | The PDF. Required unless you send file_base64. |
file_base64 |
string | The PDF as base64. A data: URI prefix is accepted and stripped. |
filename |
string | Name to store it under. Defaults to the uploaded file's name. |
destination |
enum | aws (default), google_drive, dropbox, box, onedrive. |
download_urlalways works and streams through indox.file_urlis the raw link at the destination, so for a cloud destination it points at that provider.- Sending neither
filenorfile_base64returns400 file_or_file_base64_required; unparseable base64 returns400 invalid_base64. - A cloud destination you have not connected returns
400with the codemissing_<provider>_token— connect the account first, see Integrations.
Saved PDFs appear in GET /history/ and are subject to the same
retention window as conversions.