REST API
Build with PDFOnly
Programmatic access to every tool, with simple multipart uploads, polling, and webhooks. Available on Pro and Team plans.
Authentication
All requests require a Bearer token. Generate keys in your account.
curl https://api.pdfonly.com/v1/jobs/job_abcd \ -H "Authorization: Bearer pk_live_..."
Endpoints
/v1/uploadUpload a file as raw bytes (Content-Type: application/octet-stream) with metadata in custom headers. Max 95 MB per upload. The bytes stream through our API to internal storage in one request.
Request
# Headers: # Content-Type: application/octet-stream # X-Filename: report.pdf (URL-encoded for non-ASCII) # X-Tool: merge-pdf # X-File-Type: application/pdf (optional; sniffed from extension if absent) # Body: <raw file bytes>
Response
{
"fileId": "ckxyz123",
"filename": "report.pdf",
"size": 234567,
"expiresAt": "2026-05-07T10:30:00Z"
}/v1/tools/:toolDispatch a tool job. Returns a job ID to poll.
Request
{
"fileIds": ["ckxyz123", "ckabc456"],
"params": { "level": "recommended" }
}Response
{
"jobId": "job_abcd1234",
"status": "queued"
}/v1/jobs/:idPoll job status. When status=completed, outputs include same-origin downloadUrl paths. Hit them with the same auth as the job to stream the file.
Response
{
"jobId": "job_abcd1234",
"status": "completed",
"outputs": [
{
"id": "file_xyz",
"filename": "merged.pdf",
"size": 12345,
"downloadUrl": "/api/download/file_xyz"
}
]
}/v1/download/:fileIdStream a file owned by the caller. Returns the bytes with attachment Content-Disposition. Same auth as the rest of the API.
Response
# Streaming binary response with headers: # Content-Type: application/pdf # Content-Length: 12345 # Content-Disposition: attachment; filename="merged.pdf"
Need OpenAPI / SDKs?
A full OpenAPI 3.1 spec lives at /api/v1/openapi.json. Generate typed clients for your language of choice with openapi-typescript, openapi-generator, or openapi-fetch.