Overview
PDF Tools provides twelve operations through POST /v1/pdf. The service ID is pdf-tools; the API contract is pdf-v1. This version is in testnet preparation. Registration, supplier activation and relay validation are pending.
Future relay access requires a configured Pocket gateway or supplier relay. The public https://pdf.pokt.online/ host serves the website, documentation, schema, bounded console and results; it is not a public gateway for unrestricted /v1/pdf calls. The raw OpenAPI schema is generated from the actual backend contract.
JSON request
{
"operation": "inspect",
"input_urls": ["https://example.com/sample.pdf"],
"options": {}
}URL inputs must be public HTTPS URLs without embedded credentials, fragments or custom ports. Only merge accepts more than one input.
Multipart request
Send operation as a string, options as a JSON object encoded in a string, and one PDF in file. For merge, repeat the files field in the desired order. Choose uploads or JSON URL inputs; do not mix source types in an API request.
JSON response
Every API success and error is a JSON object. Inspect and check return data with no PDF output. Other operations return outputs containing temporary HTTPS URLs and PDF metadata; PDF bytes are never returned inline in a relay response.
{
"ok": true,
"service": "pdf-tools",
"operation": "rotate",
"data": {"input_count": 1, "input_page_count": 2},
"outputs": [{
"url": "https://pdf.pokt.online/results/123e4567-e89b-42d3-a456-426614174000.pdf",
"bytes": 2048,
"page_count": 2,
"expires_at": "2026-10-08T16:00:00+00:00"
}],
"notes": ["Digital signatures are invalidated by rewriting."]
}The response shown is illustrative; identifiers, sizes and notes vary. Results expire at the returned expires_at timestamp. If a development deployment returns a relative result URL, resolve it against that deployment host. Generated outputs are unencrypted unless encrypt is selected. Rewrites invalidate existing digital signatures. Page-copy operations can omit document bookmarks and carry shared form fields outside the selected pages; review outputs before relying on them.
Operations
| Operation | Input | Result |
|---|---|---|
inspect | One PDF | Metadata and structural information |
check | One PDF | Structural check summary |
split | One PDF | One or more PDFs |
merge | Multiple PDFs, in order | One combined PDF |
extract_pages | One PDF | One PDF in selected page order |
rotate | One PDF | One PDF with relative rotation |
linearize | One PDF | One PDF prepared for progressive viewing |
optimize_structure | One PDF | One PDF with optimized structural storage |
remove_metadata | One PDF | One PDF without document information / XMP metadata |
encrypt | One PDF | One password-protected PDF |
decrypt | One PDF | One unencrypted PDF |
repair | One PDF | One rewritten PDF, if recoverable |
Parameters below belong in options. All operations accept an optional password for an encrypted input, limited to 1,024 UTF-8 bytes. Unsupported options and unknown request fields are rejected. Use only the listed fields; arbitrary command-line flags and paths are not accepted.
Inspect
Request
One PDF. Reads metadata and structural information without generating a PDF.
Parameters
password: optional input password. No other options.
Response
data includes page count, PDF version, encryption and linearization flags, forms/bookmarks/metadata presence, page rotations and warning count. outputs is empty. Raw document metadata values are not returned.
Example
{"operation":"inspect","input_urls":["https://example.com/sample.pdf"],"options":{}}Error
An encrypted input with a missing or incorrect password returns password_required_or_incorrect.
Check
Request
One PDF. Checks structural syntax and streams, including linearization when present.
Parameters
password: optional input password. No other options.
Response
data includes structurally_valid, issue_count, warning_count and linearization information. outputs is empty. A successful API response can report structurally_valid: false; inspect the check data.
Example
{"operation":"check","input_urls":["https://example.com/sample.pdf"],"options":{}}Error
A file that cannot be opened as a PDF returns invalid_pdf. The check does not certify visual rendering, malware safety or full PDF conformance.
Split
Request
One PDF. Divides consecutive pages into groups; the last output may contain fewer pages.
Parameters
pages_per_file: integer 1–500, default 1. password: optional input password.
Response
outputs contains one URL per group, in document order, with byte size, page count and expiration.
Example
{"operation":"split","input_urls":["https://example.com/sample.pdf"],"options":{"pages_per_file":2}}Error
An invalid group size returns invalid_request. A document exceeding the page budget returns too_many_pages.
Merge
Request
Multiple PDFs, up to ten inputs. Output order follows input_urls or multipart files order.
Parameters
password: optional shared input password. Alternatively, passwords: optional array containing one password or null per input. Use one password mode at a time.
Response
One generated PDF in outputs. data.input_page_count reports the combined input pages. Document bookmarks are omitted. Form field name collisions may be renamed.
Example
{"operation":"merge","input_urls":["https://example.com/first.pdf","https://example.com/second.pdf"],"options":{}}Error
Mismatched password counts return invalid_request. Excess combined pages or bytes are rejected.
Extract pages
Request
One PDF. Produces a document with the requested pages in the order supplied.
Parameters
pages: required, nonempty array of unique, 1-based integer page numbers. Each page must exist in the input. password: optional input password.
Response
One generated PDF. The example selects page 3 followed by page 1. Extraction is not redaction: shared form structures can contain information outside selected pages.
Example
{"operation":"extract_pages","input_urls":["https://example.com/sample.pdf"],"options":{"pages":[3,1]}}Error
A page beyond the document length returns invalid_pages. Empty, duplicate or nonpositive selections return invalid_request.
Rotate
Request
One PDF. Adds a clockwise rotation to selected pages, relative to their existing rotation.
Parameters
angle: required integer, 90, 180 or 270. pages: optional unique, 1-based page array; omit to rotate all pages. password: optional input password.
Response
One generated PDF with updated page rotation. Page content is not rasterized.
Example
{"operation":"rotate","input_urls":["https://example.com/sample.pdf"],"options":{"angle":90,"pages":[1,2]}}Error
Unsupported angles return invalid_request. Out-of-range pages return invalid_pages.
Linearize
Request
One PDF. Reorders its structure for progressive viewing in compatible readers.
Parameters
password: optional input password. No other options.
Response
One generated PDF. Linearization may increase file size. It does not guarantee faster viewing in every reader or on every network.
Example
{"operation":"linearize","input_urls":["https://example.com/sample.pdf"],"options":{}}Error
An output exceeding the storage budget returns output_too_large.
Optimize structure
Request
One PDF. Optimizes structural storage while preserving page content and existing compressed image streams.
Parameters
password: optional input password. No compression-quality, image-downsampling or arbitrary processing flags.
Response
One generated PDF. This is structural optimization; a smaller file is not guaranteed.
Example
{"operation":"optimize_structure","input_urls":["https://example.com/sample.pdf"],"options":{}}Error
Resource-budget exhaustion returns resource_limit; generated output exceeding its byte limit returns output_too_large.
Remove metadata
Request
One PDF. Removes document information (DocInfo) and XMP metadata.
Parameters
password: optional input password. No other options.
Response
One generated PDF. Visible content, attachments and other embedded information can remain. This operation is not redaction or a guarantee of anonymity.
Example
{"operation":"remove_metadata","input_urls":["https://example.com/sample.pdf"],"options":{}}Error
Unreadable PDF structure returns invalid_pdf; a failed rewrite returns processing_failed.
Encrypt
Request
One PDF. Creates a password-protected output. Supply the existing input password separately if the source is encrypted.
Parameters
owner_password and user_password: required new passwords, 8–127 UTF-8 bytes each. password: optional input password.
Response
One encrypted PDF. Passwords are not included in the response. Encryption does not sanitize content or preserve existing digital signatures.
Example
{"operation":"encrypt","input_urls":["https://example.com/sample.pdf"],"options":{"owner_password":"example-owner-password","user_password":"example-user-password"}}Example passwords are placeholders. Choose your own; never commit real passwords to source code.
Error
Missing or invalid new passwords return invalid_request. An incorrect input password returns password_required_or_incorrect.
Decrypt
Request
One PDF you are authorized to process. Removes encryption from the output.
Parameters
password: input password, needed when the PDF requires one. No other options.
Response
One unencrypted PDF. Its temporary download link can be used by anyone who obtains it before expiration.
Example
{"operation":"decrypt","input_urls":["https://example.com/encrypted.pdf"],"options":{"password":"example-input-password"}}Error
A missing or incorrect input password returns password_required_or_incorrect.
Repair
Request
One PDF. Attempts recovery and rewriting of recoverable document structure.
Parameters
password: optional input password. No other options.
Response
One generated PDF when recovery succeeds, with a recovery warning count in data. A successful rewrite does not prove correct visual rendering. Lost content cannot be recreated.
Example
{"operation":"repair","input_urls":["https://example.com/damaged.pdf"],"options":{}}Error
An unrecoverable input returns invalid_pdf or processing_failed.
Limits
| Budget | API | Test Console |
|---|---|---|
| Input size per PDF | 50 MB (50,000,000 bytes) | 10 MB (10,000,000 bytes) |
| Total input size | 100 MB | 20 MB |
| Merge inputs | Up to 10 | 2–5 |
| Combined input pages | 500 | 100 |
| Operation deadline | 60 seconds | 30 seconds |
| Concurrent business requests | 1 | 1 in flight |
| Generated PDF result lifetime | Up to 3,600 seconds | Up to 3,600 seconds |
Byte limits apply to uploads and URL downloads. Page limits apply to the sum of all inputs. Requests and generated outputs are bounded by additional memory and storage budgets. Download result files within one hour; treat expired URLs as unusable.
Errors
Check the HTTP status and ok. An error contains a stable error.code and a public message. Validation errors do not echo input passwords.
{"ok":false,"service":"pdf-tools","error":{"code":"invalid_pages","message":"A selected page is outside the input PDF."}}| Code | Meaning / handling |
|---|---|
invalid_request | Unsupported or malformed fields. Correct the request before retrying. |
password_required_or_incorrect | Provide the correct input password. |
invalid_pdf / empty_pdf | Unreadable PDF, or a document with no pages. Check the source. |
invalid_pages | A requested page does not exist. |
too_many_pages | Combined input pages exceed the allowed budget. |
output_too_large / resource_limit | Processing or generated output exceeds a budget. Use a smaller request. |
request_too_large / input_too_large | HTTP 413. Reduce request or PDF byte size. |
unsupported_media_type | HTTP 415. Send JSON or supported multipart data. |
invalid_url / unsafe_url | HTTP 422. Use a permitted public HTTPS destination. |
remote_http_error / remote_network_error | HTTP 502. The remote PDF server is unavailable or unsuccessful. |
input_timeout / remote_timeout / job_timeout | HTTP 504. Transfer or processing exceeded its deadline. |
result_quota_exceeded | HTTP 507. Temporary output storage is full; retry later. |
result_not_found | HTTP 404. The result is missing or has expired. |
service_busy | HTTP 429. The single processing slot is occupied. Retry later with bounded backoff. |
processing_failed | The operation could not finish. Check the input and operation. |
Download restrictions, size limits, unavailable storage and deadlines also return JSON errors. The OpenAPI schema documents the complete response shape. Do not retry invalid requests without changing their cause.
Security
Inputs are temporary and are not retained as permanent uploads. Generated files use UUID filenames and expire within one hour. Result URLs are bearer links. Public HTTPS sources are checked against network restrictions; private and local destinations are prohibited. Only allowlisted operations and fixed parameters are accepted.
Encryption does not sanitize a PDF, metadata removal is not redaction, structural checking is not a malware scan, and rewrites invalidate existing digital signatures. Generated outputs are unencrypted unless encrypt is used. Read the full security and retention notes before sending documents.
Examples
Replace GATEWAY_BASE_URL with your configured gateway or relay address and use its authentication requirements. The public documentation host does not expose the full backend API.
JSON URL input
curl -X POST "$GATEWAY_BASE_URL/v1/pdf" \
-H 'Content-Type: application/json' \
--data '{"operation":"rotate","input_urls":["https://example.com/sample.pdf"],"options":{"angle":90}}'One uploaded PDF
curl -X POST "$GATEWAY_BASE_URL/v1/pdf" \
-F 'operation=split' \
-F 'file=@sample.pdf;type=application/pdf' \
-F 'options={"pages_per_file":2}'Merge uploads in order
curl -X POST "$GATEWAY_BASE_URL/v1/pdf" \
-F 'operation=merge' \
-F 'files=@first.pdf;type=application/pdf' \
-F 'files=@second.pdf;type=application/pdf' \
-F 'options={}'Browser demo contract
The Test Console obtains a temporary {token, session_id} response from GET /test/api/session. It sends multipart operation, options and file or files to POST /test/api/run, with X-Console-Token and X-Console-Session headers. URL demo inputs send JSON with operation, input_urls and options, using Content-Type: application/json. The proxy is restricted to the PDF contract and uses lower limits. It sends no blockchain relays.
Service probes
GET /v1/identity identifies pdf-tools and version 0.1.0. GET /v1/health checks readiness. POST /v1/self-test runs a small functional probe. All probe responses are JSON.