REST APIv1

API Reference

Build PDF workflows programmatically. Import files, apply transformations, and export results - all in a single API call.

Base URLapi.supapdf.com/v1
Get API Key
Intro

Overview

The SupaPDF API lets you build PDF workflows programmatically. Create jobs with chained tasks - import a file, transform it, and export the result - all in a single request.

Every operation follows the same pipeline: import → process → export. Tasks reference each other by name, and the API executes them in dependency order automatically.

Base URL

HTTPShttps://api.supapdf.com/v1

Request format

All request bodies must be JSON. Set Content-Type: application/json on every POST request.

Versioning

Current version: v1. Breaking changes ship under a new version prefix. The previous version remains available for 12 months after a new version is released.

request.sh
# All requests follow this pattern
curl -X POST https://api.supapdf.com/v1/jobs \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "tasks": {
      "import-1":   { "operation": "import/url", "url": "..." },
      "compress-1": { "operation": "compress", "input": "import-1" },
      "export-1":   { "operation": "export/url", "input": "compress-1" }
    }
  }'
Intro

Authentication

All API requests require bearer token authentication. Include your API key in theAuthorization header of every request.

Key prefixes

sk_live_...Live key - counts against your plan quota
sk_test_...Test key - free, outputs are watermarked

Never expose API keys in client-side code or public repositories. Use environment variables and keep keys server-side only.

Revoking keys

Revoke any key from Dashboard → API Keys. Revoked keys return 401 immediately.

bash
curl https://api.supapdf.com/v1/jobs \
  -H "Authorization: Bearer sk_live_abc123..."
  -H "Content-Type: application/json"
401.json
{
  "code": "unauthorized",
  "message": "Invalid or missing API key.",
  "doc_url": "https://supapdf.com/docs#authentication"
}
Intro

Quickstart

Compress a PDF from a public URL and get a download link - the most common SupaPDF workflow in a single request.

01

Import

Define an import/url task pointing to your file.

02

Process

Add a compress task that takes the import as input.

03

Export

Add an export/url task to get a download link.

04

Poll or webhook

Poll GET /jobs/{id} until status is finished, or receive a webhook callback.

create-job.sh
curl -X POST https://api.supapdf.com/v1/jobs \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "tag": "compress-example",
    "tasks": {
      "import-1": {
        "operation": "import/url",
        "url": "https://example.com/report.pdf"
      },
      "compress-1": {
        "operation": "compress",
        "input": "import-1",
        "quality": "medium"
      },
      "export-1": {
        "operation": "export/url",
        "input": "compress-1"
      }
    }
  }'
response.json
// Job created
{
  "id": "job_01hx4k9m2p",
  "status": "processing",
  "tag": "compress-example",
  "created_at": "2026-05-01T10:23:00Z"
}

// After polling GET /v1/jobs/job_01hx4k9m2p
{
  "id": "job_01hx4k9m2p",
  "status": "finished",
  "tasks": {
    "export-1": {
      "result": {
        "files": [{
          "filename": "report.pdf",
          "url": "https://cdn.supapdf.com/dl/...",
          "size": 148201,
          "expires_at": "2026-05-02T10:23:00Z"
        }]
      }
    }
  }
}
Core

Jobs

A job is a container for one or more tasks. Tasks can reference each other's output by task name. The API resolves the dependency graph and executes tasks in the correct order automatically.

Job lifecycle

createdJob received, queued for processing
processingOne or more tasks are actively running
finishedAll tasks completed successfully
failedOne or more tasks encountered an error
cancelledJob was cancelled before completion

Create a job

POST/v1/jobs
ParamTypeDescription
tasksreqobjectNamed task definitions. Each key is a task name used as input by other tasks.
tagstringOptional label for filtering in list endpoints.
webhook_urlstringURL to POST when the job finishes. Overrides account webhook settings.

List jobs

GET/v1/jobs
ParamTypeDescription
statusstringFilter: created | processing | finished | failed
tagstringFilter by tag.
limitintegerResults per page. Default: 25, max: 100.
afterstringPagination cursor - last ID from previous page.

Get a job

GET/v1/jobs/{id}
list-jobs.sh
curl "https://api.supapdf.com/v1/jobs?limit=10&status=finished" \
  -H "Authorization: Bearer sk_live_..."
jobs-response.json
{
  "data": [
    {
      "id": "job_01hx4k9m2p",
      "status": "finished",
      "tag": "compress-example",
      "created_at": "2026-05-01T10:23:00Z",
      "finished_at": "2026-05-01T10:23:04Z"
    }
  ],
  "has_more": false,
  "total": 1
}

// GET /v1/jobs/{id} - includes task results
{
  "id": "job_01hx4k9m2p",
  "status": "finished",
  "tasks": {
    "import-1":   { "status": "finished" },
    "compress-1": { "status": "finished" },
    "export-1": {
      "status": "finished",
      "result": {
        "files": [{
          "filename": "output.pdf",
          "url": "https://cdn.supapdf.com/...",
          "size": 148201,
          "expires_at": "2026-05-02T10:23:00Z"
        }]
      }
    }
  }
}
Core

Tasks

Tasks are the individual steps within a job. Each task has an operation field plus operation-specific parameters. The input field accepts a single task name or an array of names (for operations like merge).

Task lifecycle

waitingWaiting for upstream tasks to complete
processingCurrently executing
finishedCompleted successfully
failedEncountered an error

List tasks

GET/v1/tasks?job_id={id}
task-object.json
{
  "id": "task_9xkq2v",
  "job_id": "job_01hx4k9m2p",
  "operation": "compress",
  "status": "finished",
  "created_at": "2026-05-01T10:23:00Z",
  "finished_at": "2026-05-01T10:23:03Z",
  "result": {
    "files": [
      {
        "filename": "compressed.pdf",
        "size": 148201,
        "url": "https://cdn.supapdf.com/..."
      }
    ]
  }
}
Import

import/url

Import a file from any publicly accessible URL. The file is fetched by SupaPDF servers at job execution time.

ParamTypeDescription
operationreqstringMust be "import/url".
urlreqstringPublicly accessible URL of the file.
filenamestringOverride the filename. Defaults to the URL filename.
headersobjectCustom HTTP headers when fetching (e.g. Authorization for private CDNs).
json
{
  "tasks": {
    "import-1": {
      "operation": "import/url",
      "url": "https://example.com/invoice.pdf",
      "filename": "invoice.pdf"
    }
  }
}
Import

import/upload

Get a presigned upload URL for direct file uploads from a browser or server. Create the job first, then PUT the file to the returned upload URL before the job starts.

ParamTypeDescription
operationreqstringMust be "import/upload".
filenamereqstringName of the file to upload.
file_sizeintegerFile size in bytes. Recommended for server-side validation.

The presigned URL expires in 30 minutes. Upload the file before the window closes.

create-job.json
{
  "tasks": {
    "import-1": {
      "operation": "import/upload",
      "filename": "contract.pdf"
    },
    "compress-1": { "operation": "compress", "input": "import-1" },
    "export-1":   { "operation": "export/url", "input": "compress-1" }
  }
}

// Response includes an upload URL
{
  "id": "job_01hx4k9m2p",
  "status": "waiting_for_upload",
  "tasks": {
    "import-1": {
      "result": {
        "upload_url": "https://upload.supapdf.com/...",
        "upload_method": "PUT",
        "upload_expires_at": "2026-05-01T10:53:00Z"
      }
    }
  }
}
upload.sh
# Upload the actual file
curl -X PUT "https://upload.supapdf.com/..." \
  -H "Content-Type: application/pdf" \
  --data-binary @contract.pdf
Import

import/base64

Embed a file directly in the request body as base64. Suitable for files up to 1.5 MB.

ParamTypeDescription
operationreqstringMust be "import/base64".
filereqstringBase64-encoded file content.
filenamereqstringFilename including extension.

For files larger than 1.5 MB use import/upload or import/url instead.

json
{
  "tasks": {
    "import-1": {
      "operation": "import/base64",
      "filename": "form.pdf",
      "file": "JVBERi0xLjQKJeLjz9MKNCAwIG9iago..."
    }
  }
}
Import

import/s3

Import a file directly from an AWS S3 bucket. The bucket must grant SupaPDF read access via IAM or bucket policy.

ParamTypeDescription
operationreqstringMust be "import/s3".
bucketreqstringS3 bucket name.
keyreqstringObject key (path) within the bucket.
regionreqstringAWS region, e.g. us-east-1.
access_key_idstringAWS access key ID. Can be saved in your dashboard instead.
secret_access_keystringAWS secret access key. Can be saved in your dashboard instead.
json
{
  "tasks": {
    "import-1": {
      "operation": "import/s3",
      "bucket": "my-documents",
      "key": "contracts/2026/q1.pdf",
      "region": "us-east-1",
      "access_key_id": "AKIAIOSFODNN7EXAMPLE",
      "secret_access_key": "wJalrXUtnFEMI/K7MDENG..."
    }
  }
}
Operation

compress

Reduce PDF file size by adjusting image DPI and applying compression algorithms while preserving visual fidelity at the selected quality level.

ParamTypeDescription
operationreqstringMust be "compress".
inputreqstringTask name of the import task.
qualitystring"low" | "medium" | "high". Default: "medium".
highMinimal size reduction, maximum fidelity
mediumBalanced - recommended for most use cases
lowMaximum compression, some visible quality loss
const res = await fetch("https://api.supapdf.com/v1/jobs", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUPAPDF_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    tasks: {
      "import-1":   { operation: "import/url", url: "https://example.com/report.pdf" },
      "compress-1": { operation: "compress", input: "import-1", quality: "medium" },
      "export-1":   { operation: "export/url", input: "compress-1" },
    },
  }),
});
const job = await res.json();
console.log(job.id);
response.json
{
  "id": "job_01hx4k9m2p",
  "status": "finished",
  "tasks": {
    "export-1": {
      "status": "finished",
      "result": {
        "files": [
          {
            "filename": "output.pdf",
            "url": "https://cdn.supapdf.com/dl/abc123/output.pdf",
            "size": 148201,
            "expires_at": "2026-05-24T10:23:00Z"
          }
        ]
      }
    }
  }
}
Operation

merge

Combine two or more PDF files into a single document. Pages are concatenated in the order the input task names are listed.

ParamTypeDescription
operationreqstringMust be "merge".
inputreqstring[]Array of import task names. Files are merged in the order listed.

All input files must be valid PDFs. Mixed formats are not supported in a single merge.

const res = await fetch("https://api.supapdf.com/v1/jobs", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUPAPDF_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    tasks: {
      "import-1": { operation: "import/url", url: "https://example.com/cover.pdf" },
      "import-2": { operation: "import/url", url: "https://example.com/appendix.pdf" },
      "merge-1":  { operation: "merge", input: ["import-1", "import-2"] },
      "export-1": { operation: "export/url", input: "merge-1" },
    },
  }),
});
const job = await res.json();
console.log(job.id);
response.json
{
  "id": "job_01hx4k9m2p",
  "status": "finished",
  "tasks": {
    "export-1": {
      "status": "finished",
      "result": {
        "files": [
          {
            "filename": "output.pdf",
            "url": "https://cdn.supapdf.com/dl/abc123/output.pdf",
            "size": 243780,
            "expires_at": "2026-05-24T10:23:00Z"
          }
        ]
      }
    }
  }
}
Operation

split

Split a PDF into multiple files by page ranges. Each range produces a separate output file.

ParamTypeDescription
operationreqstringMust be "split".
inputreqstringImport task name.
pagesstring[]Page range strings e.g. ["1-3","4","5-end"]. Omit to split every page individually.
const res = await fetch("https://api.supapdf.com/v1/jobs", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUPAPDF_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    tasks: {
      "import-1": { operation: "import/url", url: "https://example.com/report.pdf" },
      "split-1":  { operation: "split", input: "import-1", pages: ["1-5", "6-10", "11-end"] },
      "export-1": { operation: "export/url", input: "split-1" },
    },
  }),
});
const job = await res.json();
console.log(job.id);
response.json
{
  "id": "job_01hx4k9m2p",
  "status": "finished",
  "tasks": {
    "export-1": {
      "status": "finished",
      "result": {
        "files": [
          {
            "filename": "output-1.pdf",
            "url": "https://cdn.supapdf.com/dl/abc123/output-1.pdf",
            "size": 84512,
            "expires_at": "2026-05-24T10:23:00Z"
          },
          {
            "filename": "output-2.pdf",
            "url": "https://cdn.supapdf.com/dl/abc123/output-2.pdf",
            "size": 63689,
            "expires_at": "2026-05-24T10:23:00Z"
          },
          {
            "filename": "output-3.pdf",
            "url": "https://cdn.supapdf.com/dl/abc123/output-3.pdf",
            "size": 51204,
            "expires_at": "2026-05-24T10:23:00Z"
          }
        ]
      }
    }
  }
}
Operation

convert

Convert PDFs to Office formats (and vice versa). Supports Word, Excel, PowerPoint, and image formats.

ParamTypeDescription
operationreqstringMust be "convert".
inputreqstringImport task name.
output_formatreqstringTarget format (see supported formats below).

Supported formats

PDF → Other

docxxlsxpptxjpgpnghtmltxt

Other → PDF

docxxlsxpptxjpgpnghtml
const res = await fetch("https://api.supapdf.com/v1/jobs", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUPAPDF_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    tasks: {
      "import-1":  { operation: "import/url", url: "https://example.com/report.pdf" },
      "convert-1": { operation: "convert", input: "import-1", output_format: "docx" },
      "export-1":  { operation: "export/url", input: "convert-1" },
    },
  }),
});
const job = await res.json();
console.log(job.id);
response.json
{
  "id": "job_01hx4k9m2p",
  "status": "finished",
  "tasks": {
    "export-1": {
      "status": "finished",
      "result": {
        "files": [
          {
            "filename": "output.docx",
            "url": "https://cdn.supapdf.com/dl/abc123/output.docx",
            "size": 92840,
            "expires_at": "2026-05-24T10:23:00Z"
          }
        ]
      }
    }
  }
}
Operation

ocr

Add a searchable text layer to a scanned PDF. The original image is preserved while text becomes selectable and searchable.

ParamTypeDescription
operationreqstringMust be "ocr".
inputreqstringImport task name.
languagestringPrimary language using ISO 639-1 code. Default: en.
output_formatstring"pdf" (searchable PDF, default) or "txt" (plain text).
const res = await fetch("https://api.supapdf.com/v1/jobs", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUPAPDF_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    tasks: {
      "import-1": { operation: "import/url", url: "https://example.com/scanned.pdf" },
      "ocr-1":    { operation: "ocr", input: "import-1", language: "en", output_format: "pdf" },
      "export-1": { operation: "export/url", input: "ocr-1" },
    },
  }),
});
const job = await res.json();
console.log(job.id);
response.json
{
  "id": "job_01hx4k9m2p",
  "status": "finished",
  "tasks": {
    "export-1": {
      "status": "finished",
      "result": {
        "files": [
          {
            "filename": "output.pdf",
            "url": "https://cdn.supapdf.com/dl/abc123/output.pdf",
            "size": 312450,
            "expires_at": "2026-05-24T10:23:00Z"
          }
        ]
      }
    }
  }
}
Operation

protect

Password-protect a PDF with an open password (encryption) and/or an owner password (permissions control).

ParamTypeDescription
operationreqstringMust be "protect".
inputreqstringImport task name.
user_passwordstringPassword required to open the document.
owner_passwordstringPassword that controls permission restrictions.
allow_printbooleanPermit printing. Default: true.
allow_copybooleanPermit text copying. Default: true.
allow_modifybooleanPermit editing. Default: false.
const res = await fetch("https://api.supapdf.com/v1/jobs", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUPAPDF_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    tasks: {
      "import-1":  { operation: "import/url", url: "https://example.com/contract.pdf" },
      "protect-1": { operation: "protect", input: "import-1", user_password: "open-secret", allow_print: true, allow_copy: false, allow_modify: false },
      "export-1":  { operation: "export/url", input: "protect-1" },
    },
  }),
});
const job = await res.json();
console.log(job.id);
response.json
{
  "id": "job_01hx4k9m2p",
  "status": "finished",
  "tasks": {
    "export-1": {
      "status": "finished",
      "result": {
        "files": [
          {
            "filename": "output.pdf",
            "url": "https://cdn.supapdf.com/dl/abc123/output.pdf",
            "size": 198340,
            "expires_at": "2026-05-24T10:23:00Z"
          }
        ]
      }
    }
  }
}
Operation

unlock

Remove password protection from a PDF. You must supply the current owner or user password.

ParamTypeDescription
operationreqstringMust be "unlock".
inputreqstringImport task name.
passwordreqstringCurrent document password.
const res = await fetch("https://api.supapdf.com/v1/jobs", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUPAPDF_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    tasks: {
      "import-1": { operation: "import/url", url: "https://example.com/protected.pdf" },
      "unlock-1": { operation: "unlock", input: "import-1", password: "open-secret" },
      "export-1": { operation: "export/url", input: "unlock-1" },
    },
  }),
});
const job = await res.json();
console.log(job.id);
response.json
{
  "id": "job_01hx4k9m2p",
  "status": "finished",
  "tasks": {
    "export-1": {
      "status": "finished",
      "result": {
        "files": [
          {
            "filename": "output.pdf",
            "url": "https://cdn.supapdf.com/dl/abc123/output.pdf",
            "size": 176820,
            "expires_at": "2026-05-24T10:23:00Z"
          }
        ]
      }
    }
  }
}
Operation

watermark

Add a text watermark to every page of a PDF.

ParamTypeDescription
operationreqstringMust be "watermark".
inputreqstringImport task name.
textreqstringWatermark text content.
opacitynumber0.0 to 1.0. Default: 0.3.
rotationintegerDegrees. Default: 45.
font_sizeintegerPoints. Default: 48.
colorstringHex color. Default: "#000000".
pagesstring"all", "1-5", "1,3,5". Default: "all".
const res = await fetch("https://api.supapdf.com/v1/jobs", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUPAPDF_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    tasks: {
      "import-1":    { operation: "import/url", url: "https://example.com/draft.pdf" },
      "watermark-1": { operation: "watermark", input: "import-1", text: "CONFIDENTIAL", opacity: 0.25, rotation: 45, font_size: 52, color: "#cc0000" },
      "export-1":    { operation: "export/url", input: "watermark-1" },
    },
  }),
});
const job = await res.json();
console.log(job.id);
response.json
{
  "id": "job_01hx4k9m2p",
  "status": "finished",
  "tasks": {
    "export-1": {
      "status": "finished",
      "result": {
        "files": [
          {
            "filename": "output.pdf",
            "url": "https://cdn.supapdf.com/dl/abc123/output.pdf",
            "size": 204930,
            "expires_at": "2026-05-24T10:23:00Z"
          }
        ]
      }
    }
  }
}
Operation

sign

Place a signature image at specific coordinates on a PDF page. Useful for programmatically applying pre-approved signature images.

ParamTypeDescription
operationreqstringMust be "sign".
inputreqstringImport task name.
signaturereqstringBase64-encoded PNG of the signature.
pageintegerPage number (1-indexed). Default: last page.
xnumberX position as % of page width (0–100).
ynumberY position as % of page height (0–100).
widthnumberSignature width as % of page width.
const res = await fetch("https://api.supapdf.com/v1/jobs", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUPAPDF_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    tasks: {
      "import-1": { operation: "import/url", url: "https://example.com/agreement.pdf" },
      "sign-1":   { operation: "sign", input: "import-1", signature: "iVBORw0KGgoAAAANSUhEUgAA...", page: 3, x: 60, y: 85, width: 25 },
      "export-1": { operation: "export/url", input: "sign-1" },
    },
  }),
});
const job = await res.json();
console.log(job.id);
response.json
{
  "id": "job_01hx4k9m2p",
  "status": "finished",
  "tasks": {
    "export-1": {
      "status": "finished",
      "result": {
        "files": [
          {
            "filename": "output.pdf",
            "url": "https://cdn.supapdf.com/dl/abc123/output.pdf",
            "size": 187650,
            "expires_at": "2026-05-24T10:23:00Z"
          }
        ]
      }
    }
  }
}
Operation

redact

Permanently remove sensitive content from a PDF. True redaction removes the underlying data from the file - it cannot be recovered, unlike covering content with a shape.

ParamTypeDescription
operationreqstringMust be "redact".
inputreqstringImport task name.
regionsreqobject[]Array of { page, x, y, width, height } - all values as % of page dimensions.
fill_colorstringRedaction fill color. Default: "#000000".

Redaction is permanent and irreversible. Always verify regions on a test file before processing production documents.

const res = await fetch("https://api.supapdf.com/v1/jobs", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUPAPDF_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    tasks: {
      "import-1": { operation: "import/url", url: "https://example.com/report.pdf" },
      "redact-1": { operation: "redact", input: "import-1", fill_color: "#000000",
        regions: [
          { page: 1, x: 10, y: 20, width: 30, height: 5 },
          { page: 2, x: 40, y: 60, width: 40, height: 4 },
        ]},
      "export-1": { operation: "export/url", input: "redact-1" },
    },
  }),
});
const job = await res.json();
console.log(job.id);
response.json
{
  "id": "job_01hx4k9m2p",
  "status": "finished",
  "tasks": {
    "export-1": {
      "status": "finished",
      "result": {
        "files": [
          {
            "filename": "output.pdf",
            "url": "https://cdn.supapdf.com/dl/abc123/output.pdf",
            "size": 162140,
            "expires_at": "2026-05-24T10:23:00Z"
          }
        ]
      }
    }
  }
}
Operation

rotate

Rotate pages in a PDF by 90, 180, or 270 degrees.

ParamTypeDescription
operationreqstringMust be "rotate".
inputreqstringImport task name.
anglereqintegerRotation angle: 90, 180, or 270.
pagesstring"all", "1,3", "2-4". Default: "all".
const res = await fetch("https://api.supapdf.com/v1/jobs", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUPAPDF_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    tasks: {
      "import-1": { operation: "import/url", url: "https://example.com/scan.pdf" },
      "rotate-1": { operation: "rotate", input: "import-1", angle: 90, pages: "1,3" },
      "export-1": { operation: "export/url", input: "rotate-1" },
    },
  }),
});
const job = await res.json();
console.log(job.id);
response.json
{
  "id": "job_01hx4k9m2p",
  "status": "finished",
  "tasks": {
    "export-1": {
      "status": "finished",
      "result": {
        "files": [
          {
            "filename": "output.pdf",
            "url": "https://cdn.supapdf.com/dl/abc123/output.pdf",
            "size": 155320,
            "expires_at": "2026-05-24T10:23:00Z"
          }
        ]
      }
    }
  }
}
Export

export/url

Generate a temporary public download URL for the processed file. Links expire after 24 hours by default.

ParamTypeDescription
operationreqstringMust be "export/url".
inputreqstringProcessing task name to export.
filenamestringOverride the output filename.
expires_inintegerLink expiry in seconds. Default: 86400 (24h). Max: 604800 (7d). Premium only.
export-result.json
// Task definition
{
  "export-1": {
    "operation": "export/url",
    "input": "compress-1",
    "filename": "compressed_report.pdf",
    "expires_in": 3600
  }
}

// Result in finished job
{
  "export-1": {
    "status": "finished",
    "result": {
      "files": [{
        "filename": "compressed_report.pdf",
        "size": 148201,
        "url": "https://cdn.supapdf.com/dl/abc123/compressed_report.pdf",
        "expires_at": "2026-05-01T11:23:00Z"
      }]
    }
  }
}
Export

export/s3

Save the processed file directly to an AWS S3 bucket.

ParamTypeDescription
operationreqstringMust be "export/s3".
inputreqstringProcessing task name to export.
bucketreqstringTarget S3 bucket name.
keyreqstringObject key (path) to write.
regionreqstringAWS region.
access_key_idstringAWS access key ID.
secret_access_keystringAWS secret access key.
aclstring"private" | "public-read". Default: "private".
json
{
  "tasks": {
    "export-1": {
      "operation": "export/s3",
      "input": "compress-1",
      "bucket": "my-output-bucket",
      "key": "processed/report-compressed.pdf",
      "region": "us-east-1",
      "access_key_id": "AKIAIOSFODNN7EXAMPLE",
      "secret_access_key": "wJalrXUtnFEMI...",
      "acl": "private"
    }
  }
}
Export

export/base64

Return the processed file as a base64-encoded string inline in the job result. Best for small files that need to be consumed directly without a download step.

ParamTypeDescription
operationreqstringMust be "export/base64".
inputreqstringProcessing task name to export.

Avoid export/base64 for files larger than 1.5 MB - use export/url instead to avoid large response payloads.

base64-result.json
{
  "export-1": {
    "status": "finished",
    "result": {
      "files": [{
        "filename": "output.pdf",
        "content": "JVBERi0xLjQKJeLjz9MK...",
        "size": 48201,
        "mime_type": "application/pdf"
      }]
    }
  }
}
Webhooks

Webhooks

Webhooks deliver HTTP notifications when jobs and tasks change state - eliminating polling. Register an endpoint and select the events you care about.

Events

job.createdA new job was accepted
job.finishedAll tasks in the job completed
job.failedOne or more tasks failed
task.createdA task was queued
task.finishedA single task completed
task.failedA single task failed

Signature verification

Every delivery includes an X-SupaPDF-Signature header - an HMAC-SHA256 of the raw request body signed with your webhook secret. Always verify this before processing the payload.

webhook-payload.json
// Event: job.finished
{
  "event": "job.finished",
  "created_at": "2026-05-01T10:23:04Z",
  "data": {
    "id": "job_01hx4k9m2p",
    "status": "finished",
    "tag": "compress-example",
    "tasks": {
      "export-1": {
        "status": "finished",
        "result": {
          "files": [{
            "filename": "output.pdf",
            "url": "https://cdn.supapdf.com/...",
            "size": 148201,
            "expires_at": "2026-05-02T10:23:00Z"
          }]
        }
      }
    }
  }
}
Webhooks

Create Webhook

POST/v1/webhooks
ParamTypeDescription
endpoint_urlreqstringHTTPS URL that will receive POST requests.
eventsreqstring[]Array of event types to subscribe to.
secretstringSecret for payload signing. Auto-generated if omitted.
bash
curl -X POST https://api.supapdf.com/v1/webhooks \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint_url": "https://myapp.com/webhooks/supapdf",
    "events": ["job.finished", "job.failed"]
  }'
webhook-created.json
{
  "id": "wh_01hx4k9m2p",
  "endpoint_url": "https://myapp.com/webhooks/supapdf",
  "events": ["job.finished", "job.failed"],
  "secret": "whsec_abc123...",
  "created_at": "2026-05-01T10:00:00Z"
}
Webhooks

List Webhooks

GET/v1/webhooks

Returns all configured webhooks for your account.

json
{
  "data": [
    {
      "id": "wh_01hx4k9m2p",
      "endpoint_url": "https://myapp.com/webhooks/supapdf",
      "events": ["job.finished", "job.failed"],
      "created_at": "2026-05-01T10:00:00Z"
    }
  ],
  "total": 1
}
Webhooks

Delete Webhook

DELETE/v1/webhooks/{id}

Permanently removes a webhook. No further events will be delivered to the endpoint.

bash
curl -X DELETE \
  https://api.supapdf.com/v1/webhooks/wh_01hx4k9m2p \
  -H "Authorization: Bearer sk_live_..."

# 204 No Content on success
Reference

Errors

All error responses include a JSON body with a machine-readable code and a human-readable message.

HTTP status codes

200OKRequest succeeded
201CreatedResource created
204No ContentSuccessful deletion
400Bad RequestInvalid body or params
401UnauthorizedMissing or invalid API key
402Payment RequiredPlan limit reached
403ForbiddenInsufficient permissions
404Not FoundResource does not exist
429Too Many RequestsRate limit exceeded
500Server ErrorRetry with exponential backoff

Application error codes

unauthorizedMissing or invalid API key
insufficient_creditsAccount has no remaining credits
file_too_largeFile exceeds plan limit
unsupported_formatInput format is not supported
processing_failedFile could not be processed
upload_timeoutFile upload was not completed in time
rate_limit_exceededToo many requests - slow down
invalid_passwordIncorrect password for a protected PDF
error-shapes.json
// Standard error
{
  "code": "insufficient_credits",
  "message": "Your account has no remaining credits.
    Upgrade your plan or purchase additional credits.",
  "doc_url": "https://supapdf.com/docs#errors"
}

// Validation error (400)
{
  "code": "invalid_request",
  "message": "Validation failed",
  "errors": [
    {
      "field": "tasks.compress-1.quality",
      "message": "Must be one of: low, medium, high"
    }
  ]
}
Reference

Rate Limits

Rate limits are enforced per API key. Exceeding a limit returns 429 Too Many Requests. Response headers tell you when the window resets.

Limits by plan

PlanReq / minConcurrentMax file
Free10215 MB
Premium60104 GB
BusinessCustomCustomCustom

Rate limit headers

X-RateLimit-LimitMax requests allowed in the window
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when window resets
Retry-AfterSeconds to wait before retrying (on 429)
bash
# Headers on every response
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1746358980

# 429 response
HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json

{
  "code": "rate_limit_exceeded",
  "message": "Rate limit exceeded. Retry after 12s.",
  "retry_after": 12
}
Reference

SDKs & Libraries

Official SDKs are coming soon. In the meantime, the REST API works with any HTTP client in any language.

Node.js / TypeScript

Use native fetch or any HTTP library (axios, got, ky).

Python

Use requests or httpx.

Community libraries

Community-maintained SDKs will be listed here as they become available. Building one? Let us know.

Get your API key

API access is available on Premium plans. Test keys (watermarked output) are free on all plans.

Open Dashboard
supapdf.ts
const res = await fetch("https://api.supapdf.com/v1/jobs", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUPAPDF_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    tasks: {
      "import-1": {
        operation: "import/url",
        url: "https://example.com/report.pdf",
      },
      "compress-1": {
        operation: "compress",
        input: "import-1",
        quality: "medium",
      },
      "export-1": {
        operation: "export/url",
        input: "compress-1",
      },
    },
  }),
});

const job = await res.json();
console.log(job.id); // job_01hx4k9m2p
supapdf.py
import os, requests

resp = requests.post(
    "https://api.supapdf.com/v1/jobs",
    headers={
        "Authorization": f"Bearer {os.environ['SUPAPDF_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={
        "tasks": {
            "import-1": {
                "operation": "import/url",
                "url": "https://example.com/report.pdf",
            },
            "compress-1": {
                "operation": "compress",
                "input": "import-1",
                "quality": "medium",
            },
            "export-1": {
                "operation": "export/url",
                "input": "compress-1",
            },
        }
    },
)
job = resp.json()
print(job["id"])  # job_01hx4k9m2p