Calculate Credit Usage

With the PSPDFKit API, you can use API credits to perform a variety of document management actions in a single request. We use an API credit system to track usage. Your credit quota will vary depending on your plan. In this guide, we’ll discuss how you can learn how many credits are spent by your requests.

Pricing per Tool

You can learn how many credits are required to use a certain API processing tool by referring to the pricing table.

Another option is to visit any of our tool pages, which contain a badge with the number of credits required to use the tool:

Tool page with credit usage badge

If you are combining multiple processing actions, your credit cost will be the sum of the credit costs of the tools you used in your combine workflow.

Analyze Build Requests

If you are using the Build API, you can calculate the number of credits required by a particular Build API request without actually executing it. The request is free of charge.

If you are processing other content types as PDFs, don't forget that conversions during the processing can also incur additional costs. The analyze request can take this into account if you also provide a content type for all of these non-PDF content types.

For example, the complex request

curl -X POST https://api.pspdfkit.com/analyze_build \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_api_key_here" \
  -o analyze_result.json \
  --fail \
  -d '{
      "parts": [
        {
          "file": "document",
          "content_type": "image/gif"
        },
        {
          "file": "document2",
          "content_type": "image/png",
          "actions": [
            {
              "type": "ocr",
              "language": "english"
            }
          ]
        }
      ],
      "actions": [
        {
          "type": "flatten"
        },
        {
          "type": "rotate",
          "rotateBy": 90
        }
      ],
      "output": {
        "type": "pdfa",
        "conformance": "pdfa-1a",
        "owner_password": "test123",
        "user_password": "test3",
        "metadata": {
          "title": "title"
        },
        "optimize": {
          "mrcCompression": true,
          "linearize": true
        }
      }
    }'
curl -X POST https://api.pspdfkit.com/analyze_build ^
  -H "Content-Type: application/json" ^
  -H "Authorization: Bearer your_api_key_here" ^
  -o analyze_result.json ^
  --fail ^
  -d "{\"parts\": [{\"file\": \"document\", \"content_type\": \"image/gif\"}, {\"file\": \"document2\", \"content_type\": \"image/png\", \"actions\": [{\"type\": \"ocr\", \"language\": \"english\"}]}], \"actions\": [{\"type\": \"flatten\"}, {\"type\": \"rotate\", \"rotateBy\": 90}], \"output\": {\"type\": \"pdfa\", \"conformance\": \"pdfa-1a\", \"owner_password\": \"test123\", \"user_password\": \"test3\", \"metadata\": {\"title\": \"title\"}, \"optimize\": {\"mrcCompression\": true, \"linearize\": true}}}"
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 = RequestBody.create(
      mediaType,
      new JSONObject()
        .put("parts", new JSONArray()
          .put(new JSONObject()
            .put("file", "document")
            .put("content_type", "image/gif")
          )
          .put(new JSONObject()
            .put("file", "document2")
            .put("content_type", "image/png")
            .put("actions", new JSONArray()
              .put(new JSONObject()
                .put("type", "ocr")
                .put("language", "english")
              )
            )
          )
        )
        .put("actions", new JSONArray()
          .put(new JSONObject()
            .put("type", "flatten")
          )
          .put(new JSONObject()
            .put("type", "rotate")
            .put("rotateBy", 90)
          )
        )
        .put("output", new JSONObject()
          .put("type", "pdfa")
          .put("conformance", "pdfa-1a")
          .put("owner_password", "test123")
          .put("user_password", "test3")
          .put("metadata", new JSONObject()
            .put("title", "title")
          )
          .put("optimize", new JSONObject()
            .put("mrcCompression", true)
            .put("linearize", true)
          )
        ).toString()
    );

    final Request request = new Request.Builder()
      .url("https://api.pspdfkit.com/analyze_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("analyze_result.json"),
        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/analyze_build");

      var request = new RestRequest(Method.POST)
        .AddHeader("Authorization", "Bearer your_api_key_here")
        .AddJsonBody(new JsonObject
          {
            ["parts"] = new JsonArray
            {
              new JsonObject
              {
                ["file"] = "document",
                ["content_type"] = "image/gif"
              },
              new JsonObject
              {
                ["file"] = "document2",
                ["content_type"] = "image/png",
                ["actions"] = new JsonArray
                {
                  new JsonObject
                  {
                    ["type"] = "ocr",
                    ["language"] = "english"
                  }
                }
              }
            },
            ["actions"] = new JsonArray
            {
              new JsonObject
              {
                ["type"] = "flatten"
              },
              new JsonObject
              {
                ["type"] = "rotate",
                ["rotateBy"] = 90
              }
            },
            ["output"] = new JsonObject
            {
              ["type"] = "pdfa",
              ["conformance"] = "pdfa-1a",
              ["owner_password"] = "test123",
              ["user_password"] = "test3",
              ["metadata"] = new JsonObject
              {
                ["title"] = "title"
              },
              ["optimize"] = new JsonObject
              {
                ["mrcCompression"] = true,
                ["linearize"] = true
              }
            }
          });

      request.AdvancedResponseWriter = (responseStream, response) =>
      {
        if (response.StatusCode == HttpStatusCode.OK)
        {
          using (responseStream)
          {
            using var outputFileWriter = File.OpenWrite("analyze_result.json");
            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: "document",
      content_type: "image/gif"
    },
    {
      file: "document2",
      content_type: "image/png",
      actions: [
        {
          type: "ocr",
          language: "english"
        }
      ]
    }
  ],
  actions: [
    {
      type: "flatten"
    },
    {
      type: "rotate",
      rotateBy: 90
    }
  ],
  output: {
    type: "pdfa",
    conformance: "pdfa-1a",
    owner_password: "test123",
    user_password: "test3",
    metadata: {
      title: "title"
    },
    optimize: {
      mrcCompression: true,
      linearize: true
    }
  }
})

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

    response.data.pipe(fs.createWriteStream("analyze_result.json"))
  } 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

body = json.dumps({
  'parts': [
    {
      'file': 'document',
      'content_type': 'image/gif'
    },
    {
      'file': 'document2',
      'content_type': 'image/png',
      'actions': [
        {
          'type': 'ocr',
          'language': 'english'
        }
      ]
    }
  ],
  'actions': [
    {
      'type': 'flatten'
    },
    {
      'type': 'rotate',
      'rotateBy': 90
    }
  ],
  'output': {
    'type': 'pdfa',
    'conformance': 'pdfa-1a',
    'owner_password': 'test123',
    'user_password': 'test3',
    'metadata': {
      'title': 'title'
    },
    'optimize': {
      'mrcCompression': true,
      'linearize': true
    }
  }
})

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

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

$FileHandle = fopen('analyze_result.json', 'w+');

$curl = curl_init();

$body = '{
  "parts": [
    {
      "file": "document",
      "content_type": "image/gif"
    },
    {
      "file": "document2",
      "content_type": "image/png",
      "actions": [
        {
          "type": "ocr",
          "language": "english"
        }
      ]
    }
  ],
  "actions": [
    {
      "type": "flatten"
    },
    {
      "type": "rotate",
      "rotateBy": 90
    }
  ],
  "output": {
    "type": "pdfa",
    "conformance": "pdfa-1a",
    "owner_password": "test123",
    "user_password": "test3",
    "metadata": {
      "title": "title"
    },
    "optimize": {
      "mrcCompression": true,
      "linearize": true
    }
  }
}';

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.pspdfkit.com/analyze_build',
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_POSTFIELDS => $body,
  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/analyze_build HTTP/1.1
Content-Type: application/json
Authorization: Bearer your_api_key_here

{
  "parts": [
    {
      "file": "document",
      "content_type": "image/gif"
    },
    {
      "file": "document2",
      "content_type": "image/png",
      "actions": [
        {
          "type": "ocr",
          "language": "english"
        }
      ]
    }
  ],
  "actions": [
    {
      "type": "flatten"
    },
    {
      "type": "rotate",
      "rotateBy": 90
    }
  ],
  "output": {
    "type": "pdfa",
    "conformance": "pdfa-1a",
    "owner_password": "test123",
    "user_password": "test3",
    "metadata": {
      "title": "title"
    },
    "optimize": {
      "mrcCompression": true,
      "linearize": true
    }
  }
}

responds with the following detailed usage statistics:

JSON
{
  "cost": 11.5,
  "required_features": {
    "annotations_api": {
      "cost": 0.5,
      "unit_cost": 0.5,
      "units": 1,
      "usage": [
        "$.actions[0]"
      ]
    },
    "compression_api": {
      "cost": 2,
      "unit_cost": 2,
      "units": 1,
      "usage": [
        "$.output"
      ]
    },
    "document_editor_api": {
      "cost": 3,
      "unit_cost": 1,
      "units": 3,
      "usage": [
        "$.parts.merge",
        "$.actions[1]",
        "$.output"
      ]
    },
    "image_conversion_api": {
      "cost": 1.0,
      "unit_cost": 0.5,
      "units": 2,
      "usage": [
        "$.parts[0]",
        "$.parts[1]"
      ]
    },
    "linearization_api": {
      "cost": 2,
      "unit_cost": 2,
      "units": 1,
      "usage": [
        "$.output"
      ]
    },
    "ocr_api": {
      "cost": 2,
      "unit_cost": 2,
      "units": 1,
      "usage": [
        "$.parts[1].actions[0]"
      ]
    },
    "pdfa_api": {
      "cost": 1,
      "unit_cost": 1,
      "units": 1,
      "usage": [
        "$.output"
      ]
    }
  }
}

Get Costs from Live Requests

If you don't want to deal with separate requests or calculate your costs from the pricing table manually, PSPDFKit API also reports the actual credit consumption in all Build and Sign API responses.

You should refer to the following custom response headers:

  • x-pspdfkit-request-cost - The actual billed cost of the request in credits.
  • x-pspdfkit-remaining-credits - The state of your remaining credits balance after the request has been executed. Note that this value is only informational, as it does not include pending credit deductions on your account.