API Overview

PSPDFKit API exposes a single HTTP endpoint for usage:

POST https://api.pspdfkit.com/build

This endpoint allows you to declaratively assemble a PDF document from multiple independent parts, applying actions on the whole output file and single parts.

The API expects data to be sent either as as multipart/form-data or application/json content types.

Multipart Request

The basic use case for the /build API is to upload all inputs together with the processing instructions with the multipart/form-data request:

curl -X POST https://api.pspdfkit.com/build \
  -H "Authorization: Bearer your_api_key_here" \
  -o result.pdf \
  --fail \
  -F document=@input-file.pdf \
  -F instructions='{
      "parts": [
        {
          "file": "document"
        }
      ],
      "actions": [
        {
          "type": "flatten"
        }
      ]
    }'
curl -X POST https://api.pspdfkit.com/build ^
  -H "Authorization: Bearer your_api_key_here" ^
  -o result.pdf ^
  --fail ^
  -F document=@input-file.pdf ^
  -F instructions="{\"parts\": [{\"file\": \"document\"}], \"actions\": [{\"type\": \"flatten\"}]}"
package com.example.pspdfkit;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

import org.json.JSONArray;
import org.json.JSONObject;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public final class PspdfkitApiExample {
  public static void main(final String[] args) throws IOException {
    final RequestBody body = new MultipartBody.Builder()
      .setType(MultipartBody.FORM)
      .addFormDataPart(
        "document",
        "input-file.pdf",
        RequestBody.create(
          new File("input-file.pdf"),
          MediaType.parse("application/pdf")
        )
      )
      .addFormDataPart(
        "instructions",
        new JSONObject()
          .put("parts", new JSONArray()
            .put(new JSONObject()
              .put("file", "document")
            )
          )
          .put("actions", new JSONArray()
            .put(new JSONObject()
              .put("type", "flatten")
            )
          ).toString()
      )
      .build();

    final Request request = new Request.Builder()
      .url("https://api.pspdfkit.com/build")
      .method("POST", body)
      .addHeader("Authorization", "Bearer your_api_key_here")
      .build();

    final OkHttpClient client = new OkHttpClient()
      .newBuilder()
      .build();

    final Response response = client.newCall(request).execute();

    if (response.isSuccessful()) {
      Files.copy(
        response.body().byteStream(),
        FileSystems.getDefault().getPath("result.pdf"),
        StandardCopyOption.REPLACE_EXISTING
      );
    } else {
      // Handle the error
      throw new IOException(response.body().string());
    }
  }
}
using System;
using System.IO;
using System.Net;
using RestSharp;

namespace PspdfkitApiDemo
{
  class Program
  {
    static void Main(string[] args)
    {
      var client = new RestClient("https://api.pspdfkit.com/build");

      var request = new RestRequest(Method.POST)
        .AddHeader("Authorization", "Bearer your_api_key_here")
        .AddFile("document", "input-file.pdf")
        .AddParameter("instructions", new JsonObject
        {
          ["parts"] = new JsonArray
          {
            new JsonObject
            {
              ["file"] = "document"
            }
          },
          ["actions"] = new JsonArray
          {
            new JsonObject
            {
              ["type"] = "flatten"
            }
          }
        }.ToString());

      request.AdvancedResponseWriter = (responseStream, response) =>
      {
        if (response.StatusCode == HttpStatusCode.OK)
        {
          using (responseStream)
          {
            using var outputFileWriter = File.OpenWrite("result.pdf");
            responseStream.CopyTo(outputFileWriter);
          }
        }
        else
        {
          var responseStreamReader = new StreamReader(responseStream);
          Console.Write(responseStreamReader.ReadToEnd());
        }
      };

      client.Execute(request);
    }
  }
}
// This code requires Node.js. Do not run this code directly in a web browser.

const axios = require('axios')
const FormData = require('form-data')
const fs = require('fs')

const formData = new FormData()
formData.append('instructions', JSON.stringify({
  parts: [
    {
      file: "document"
    }
  ],
  actions: [
    {
      type: "flatten"
    }
  ]
}))
formData.append('document', fs.createReadStream('input-file.pdf'))

;(async () => {
  try {
    const response = await axios.post('https://api.pspdfkit.com/build', formData, {
      headers: formData.getHeaders({
        'Authorization': 'Bearer your_api_key_here'
      }),
      responseType: "stream"
    })

    response.data.pipe(fs.createWriteStream("result.pdf"))
  } catch (e) {
    const errorString = await streamToString(e.response.data)
    console.log(errorString)
  }
})()

function streamToString(stream) {
  const chunks = []
  return new Promise((resolve, reject) => {
    stream.on("data", (chunk) => chunks.push(Buffer.from(chunk)))
    stream.on("error", (err) => reject(err))
    stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")))
  })
}
import requests
import json

instructions = {
  'parts': [
    {
      'file': 'document'
    }
  ],
  'actions': [
    {
      'type': 'flatten'
    }
  ]
}

response = requests.request(
  'POST',
  'https://api.pspdfkit.com/build',
  headers = {
    'Authorization': 'Bearer your_api_key_here'
  },
  files = {
    'document': open('input-file.pdf', 'rb')
  },
  data = {
    'instructions': json.dumps(instructions)
  },
  stream = True
)

if response.ok:
  with open('result.pdf', 'wb') as fd:
    for chunk in response.iter_content(chunk_size=8096):
      fd.write(chunk)
else:
  print(response.text)
  exit()
<?php

$FileHandle = fopen('result.pdf', 'w+');

$curl = curl_init();

$instructions = '{
  "parts": [
    {
      "file": "document"
    }
  ],
  "actions": [
    {
      "type": "flatten"
    }
  ]
}';

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.pspdfkit.com/build',
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_POSTFIELDS => array(
    'instructions' => $instructions,
    'document' => new CURLFILE('input-file.pdf')
  ),
  CURLOPT_HTTPHEADER => array(
    'Authorization: Bearer your_api_key_here'
  ),
  CURLOPT_FILE => $FileHandle,
));

$response = curl_exec($curl);

curl_close($curl);

fclose($FileHandle);

POST https://api.pspdfkit.com/build HTTP/1.1
Content-Type: multipart/form-data; boundary=--customboundary
Authorization: Bearer your_api_key_here

--customboundary
Content-Disposition: form-data; name="instructions"
Content-Type: application/json

{
  "parts": [
    {
      "file": "document"
    }
  ],
  "actions": [
    {
      "type": "flatten"
    }
  ]
}
--customboundary
Content-Disposition: form-data; name="document"; filename="input-file.pdf"
Content-Type: application/pdf

(document data)
--customboundary--

Simple Request

The /build API supports inputs provided from remote URLs. If all inputs are provided as remote URLs, the multipart request isn’t necessary and can be simplified to a non-multipart request with the application/json content type:

curl -X POST https://api.pspdfkit.com/build \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_api_key_here" \
  -o result.pdf \
  --fail \
  -d '{
      "parts": [
        {
          "file": {
            "url": "https://pspdfkit.com/api/downloads/samples/pdf/document.pdf"
          }
        }
      ],
      "actions": [
        {
          "type": "flatten"
        }
      ]
    }'
curl -X POST https://api.pspdfkit.com/build \
  -H "Content-Type: application/json" ^
  -H "Authorization: Bearer your_api_key_here" ^
  -o result.pdf ^
  --fail ^
  -d '{\"parts\": [{\"file\": {\"url\": \"https://pspdfkit.com/api/downloads/samples/pdf/document.pdf\"}}], \"actions\": [{\"type\": \"flatten\"}]}'
package com.example.pspdfkit;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

import org.json.JSONArray;
import org.json.JSONObject;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public final class PspdfkitApiExample {
  public static void main(final String[] args) throws IOException {
    final MediaType mediaType = MediaType.parse("application/json");
    final RequestBody body = new RequestBody.create(
      mediaType,
      new JSONObject()
        .put("parts", new JSONArray()
          .put(new JSONObject()
            .put("file", new JSONObject()
              .put("url", "https://pspdfkit.com/api/downloads/samples/pdf/document.pdf")
            )
          )
        )
        .put("actions", new JSONArray()
          .put(new JSONObject()
            .put("type", "flatten")
          )
        ).toString()
    );

    final Request request = new Request.Builder()
      .url("https://api.pspdfkit.com/build")
      .method("POST", body)
      .addHeader("Content-Type", "application/json")
      .addHeader("Authorization", "Bearer your_api_key_here")
      .build();

    final OkHttpClient client = new OkHttpClient()
      .newBuilder()
      .build();

    final Response response = client.newCall(request).execute();

    if (response.isSuccessful()) {
      Files.copy(
        response.body().byteStream(),
        FileSystems.getDefault().getPath("result.pdf"),
        StandardCopyOption.REPLACE_EXISTING
      );
    } else {
      // Handle the error
      throw new IOException(response.body().string());
    }
  }
}
using System;
using System.IO;
using System.Net;
using RestSharp;

namespace PspdfkitApiDemo
{
  class Program
  {
    static void Main(string[] args)
    {
      var client = new RestClient("https://api.pspdfkit.com/build");

      var request = new RestRequest(Method.POST)
        .AddHeader("Authorization", "Bearer your_api_key_here")
        .AddJsonBody(new JsonObject
          {
            ["parts"] = new JsonArray
            {
              new JsonObject
              {
                ["file"] = new JsonObject
                {
                  ["url"] = "https://pspdfkit.com/api/downloads/samples/pdf/document.pdf"
                }
              }
            },
            ["actions"] = new JsonArray
            {
              new JsonObject
              {
                ["type"] = "flatten"
              }
            }
          })

      request.AdvancedResponseWriter = (responseStream, response) =>
      {
        if (response.StatusCode == HttpStatusCode.OK)
        {
          using (responseStream)
          {
            using var outputFileWriter = File.OpenWrite("result.pdf");
            responseStream.CopyTo(outputFileWriter);
          }
        }
        else
        {
          var responseStreamReader = new StreamReader(responseStream);
          Console.Write(responseStreamReader.ReadToEnd());
        }
      };

      client.Execute(request);
    }
  }
}
// This code requires Node.js. Do not run this code directly in a web browser.

const axios = require('axios')
const FormData = require('form-data')
const fs = require('fs')

const body = JSON.stringify({
  parts: [
    {
      file: {
        url: "https://pspdfkit.com/api/downloads/samples/pdf/document.pdf"
      }
    }
  ],
  actions: [
    {
      type: "flatten"
    }
  ]
});

;(async () => {
  try {
    const response = await axios.post('https://api.pspdfkit.com/build', body, {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer your_api_key_here'
      }),
      responseType: "stream"
    })

    response.data.pipe(fs.createWriteStream("result.pdf"))
  } catch (e) {
    const errorString = await streamToString(e.response.data)
    console.log(errorString)
  }
})()

function streamToString(stream) {
  const chunks = []
  return new Promise((resolve, reject) => {
    stream.on("data", (chunk) => chunks.push(Buffer.from(chunk)))
    stream.on("error", (err) => reject(err))
    stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")))
  })
}
import requests
import json

instructions = {
  'parts': [
    {
      'file': {
        'url': 'https://pspdfkit.com/api/downloads/samples/pdf/document.pdf'
      }
    }
  ],
  'actions': [
    {
      'type': 'flatten'
    }
  ]
}

response = requests.request(
  'POST',
  'https://api.pspdfkit.com/build',
  headers = {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_api_key_here'
  },
  data = json.dumps(instructions),
  stream = True
)

if response.ok:
  with open('result.pdf', 'wb') as fd:
    for chunk in response.iter_content(chunk_size=8096):
      fd.write(chunk)
else:
  print(response.text)
  exit()
<?php

$FileHandle = fopen('result.pdf', 'w+');

$curl = curl_init();

$instructions = '{
  "parts": [
    {
      "file": {
        "url": "https://pspdfkit.com/api/downloads/samples/pdf/document.pdf"
      }
    }
  ],
  "actions": [
    {
      "type": "flatten"
    }
  ]
}';

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.pspdfkit.com/build',
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_POSTFIELDS => $instructions,
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Authorization: Bearer your_api_key_here'
  ),
  CURLOPT_FILE => $FileHandle,
));

$response = curl_exec($curl);

curl_close($curl);

fclose($FileHandle);

POST https://api.pspdfkit.com/build HTTP/1.1
Content-Type: application/json
Authorization: Bearer your_api_key_here

{
  "parts": [
    {
      "file": {
        "url": "https://pspdfkit.com/api/downloads/samples/pdf/document.pdf"
      }
    }
  ],
  "actions": [
    {
      "type": "flatten"
    }
  ]
}

For more details on the structure of an API request, see the API Reference.