← Back to Home

SignPDFKit SDK

Complete SDK Documentation & Integration Guide

📋 Summary

SignPDFKit provides a comprehensive solution for digitally signing and verifying PDF documents. Our SDK supports multiple signature types, integrates with HSM, and is PDF standard compliant.

Key Features

Supported Platforms

📚 Shared Library

For Desktop (Language Support)

⬇️ Download for Desktop

For Android (JNI)

⬇️ Download for Android

For iOS (XCFramework)

⬇️ Download for iOS

For Web (WebAssembly)

⬇️ Download for Web

📄 Wrapper Class

Python

⬇️ signpdfkit.py

PHP

⬇️ signpdfkit.php

Go

⬇️ signpdfkit.go

JavaScript

⬇️ signpdfkit.js

Ruby

⬇️ signpdfkit.rb

Java

⬇️ SignPDFKit.java

Rust

⬇️ signpdfkit.rs

TypeScript

⬇️ Coming Soon

C++

⬇️ Coming Soon

C#

⬇️ Coming Soon

Dart

⬇️ Coming Soon

⚙️ Setup

📄 Example Usage

TSA (TimeStamp Authority)


from signpdfkit import SignPDFKitSign, SignPDFKitVerify, Visibility, Subfilter, SignatureType, DSS  # the wrapper class
import requests  # pip install requests

options = {
    "email": "user@signpdfkit.com",
    "passphrase": "123456"
}

def sign_digest_function(digest, options_params):
# You can provide the cms here by sign the digest
# in this example is using SignPDFKit CMS Generator

    # 1) Send POST request to PHP API
    url = "https://signpdfkit.com/api/sign"
    headers = {"Content-Type": "application/json"}
    payload = {
        "digest": digest,
        "email": options_params["email"],
        "passphrase": options_params["passphrase"]
    }

    response = requests.post(url, headers=headers, json=payload)
    response.raise_for_status()  # will throw if not 2xx

    # 2) Parse JSON response from PHP
    data = response.json()

    if "cms" not in data:
        raise ValueError(f"Invalid response: {data}")

    cms = data["cms"]

    return cms

# Location of shared library
libDir = "path/to/shared/lib"  # Change this to your actual lib directory path
    
# Example usage of Sign PDF
signer = SignPDFKitSign(libDir, sign_digest_function, options)

resultSign = signer.sign_pdf(
    input_path = "input/sample.pdf",                # input pdf
    output_path = "output/signed.pdf",              # output pdf
    image_path = "input/visualization.png",         # visualization image
    url = "https://signpdfkit.com/file/1234567",    # url for qrcode
    location = "Jakarta",                           # location
    reason = "Need to Approve",                     # reason
    contact_info = "karyadi.dk@gmail.com",          # contact info
    field_id = "SignPDFKit",                        # field id
    character = "#",                                # Character
    signature_type = SignatureType.SIGNATURE,       # signature type
    page = 1,                                       # page
    field_type = Subfilter.ADBE,                    # is pades
    visibility = Visibility.VISIBLE_IMAGE,          # type
    x = 100.0,                                      # x (float)
    y = 200.0,                                      # y (float)
    width = 100.0,                                  # width (float)
    height = 100.0,                                 # height (float)
    dss = DSS.YES                                   # Document Security Store for LTV Support
)

# Example usage of Verify PDF
verifier = SignPDFKitVerify(libDir)
resultVerify = verifier.verify(
  "input/signed_document.pdf"                       # input pdf
)

require_once './signpdfkit.php'; // the wrapper class

$options = [
    "email" => "user@signpdfkit.com",
    "passphrase" => "123456"
];

// Location of shared library
$lib_dir = 'path/to/shared/lib';  // Change this to your actual lib directory path

function sign_digest_function($digest, $options_params) {
// You can provide the cms here by sign the digest
// in this example is using SignPDFKit CMS Generator

    // 1) Send POST request to PHP API
    $url = "https://signpdfkit.com/api/sign";
    
    $headers = ["Content-Type: application/json"];
    $payload = [
        "digest" => $digest,
        "email" => $options_params["email"],
        "passphrase" => $options_params["passphrase"]
    ];

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    // Raise error if not 2xx
    if ($httpCode < 200 || $httpCode >= 300) {
        throw new Exception("HTTP Error: {$httpCode} - {$response}");
    }

    // 2) Parse JSON response from PHP
    $data = json_decode($response, true);
    
    if (!isset($data['cms'])) {
        throw new Exception("Invalid response: " . $response);
    }

    return $data['cms'];
}

// Example usage of Sign PDF
try {
    $signer = new SignPDFKitSign($lib_dir, 'sign_digest_function', $options);

    $result = $signer->sign_pdf(
        input_path: "input/sample.pdf",               // input pdf
        output_path: "output/signed.pdf",             // output pdf
        image_path: "input/visualization.png",        // visualization image
        url: "https://signpdfkit.com/file/1234567",   // url for qrcode
        location: "Jakarta",                          // location
        reason: "Need to Approve",                    // reason
        contact_info: "karyadi.dk@gmail.com",         // contact info
        field_id: "SignPDFKit",                       // field id
        character: "#",                               // Character
        signature_type: SignatureType::SIGNATURE,     // signature type
        page: 1,                                      // page
        field_type: Subfilter::ADBE,                  // is pades
        visibility: Visibility::INVISIBLE,            // type
        x: 100.0,                                     // x (float)
        y: 200.0,                                     // y (float)
        width: 100.0,                                 // width (float)
        height: 100.0,                                // height (float)
        dss: DSS::YES                                 // Document Security Store for LTV Support
    );
} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}

// Example usage of Verify PDF
try {
    $verifier = new SignPDFKitVerify($lib_dir);
    $result = $verifier->verify(
      "input/signed_document.pdf"                     // input pdf
    );
} catch (Exception $e) {
    echo "Verification error: " . $e->getMessage() . "\n";
}

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

func main() {
	options := map[string]string{
		"email":      "user@signpdfkit.com",
		"passphrase": "123456",
	}

  // Location of shared library
	libDir := "path/to/shared/lib"  // Change this to your actual lib directory path

	signFn := func(digest string, options map[string]string) string {
  // You can provide the cms here by sign the digest
  // in this example is using SignPDFKit CMS Generator

		url := "https://signpdfkit.com/api/sign"

		// Prepare payload
		payload := map[string]string{
			"digest":     digest,
			"email":      options["email"],
			"passphrase": options["passphrase"],
		}
		payloadBytes, err := json.Marshal(payload)
		if err != nil {
			return ""
		}

		// Create POST request
		req, err := http.NewRequest("POST", url, bytes.NewBuffer(payloadBytes))
		if err != nil {
			return ""
		}
		req.Header.Set("Content-Type", "application/json")

		// Disable TLS verification (⚠️ not recommended for production)
		client := &http.Client{
			Transport: &http.Transport{
				// InsecureSkipVerify disables SSL verification like CURLOPT_SSL_VERIFYPEER=false
				// Import "crypto/tls" if you want to allow this
				TLSClientConfig: nil,
			},
		}

		resp, err := client.Do(req)
		if err != nil {
			return ""
		}
		defer resp.Body.Close()

		// Read response body
		body, err := io.ReadAll(resp.Body)
		if err != nil {
			return ""
		}

		// Raise error if HTTP status not 2xx
		if resp.StatusCode < 200 || resp.StatusCode >= 300 {
			return ""
		}

		// Parse JSON response
		var responseData map[string]interface{}
		if err := json.Unmarshal(body, &responseData); err != nil {
			return ""
		}

		// Validate response contains "cms"
		cms, ok := responseData["cms"].(string)
		if !ok || cms == "" {
			return ""
		}

		return cms
	}

	// Example usage of Sign PDF
	signer, _ := SignPDFKitSign(signFn, options, libDir)

	signResult := signer.SignPDF(SignArgs{
		InputPath:     "input/sample.pdf",                              // input pdf
		OutputPath:    "output/signed.pdf",                             // output pdf
		ImagePath:     strPtr("input/visualization.png"),               // visualization image
		URL:           strPtr("https://signpdfkit.com/file/1234567"),   // url for qrcode
		Location:      strPtr("Jakarta"),                               // location
		Reason:        strPtr("Need to sign"),                          // reason
		ContactInfo:   strPtr("example@gmail.com"),                     // contact info
		FieldID:       strPtr("SignPDFKit"),                            // field id
		Character:     strPtr("@"),                                     // Character
		SignatureType: intPtr(SIGNATURE),                               // signature type
		Page:          intPtr(1),                                       // page
		FieldType:     intPtr(ADBE),                                    // is pades
		Visibility:    intPtr(Invisible),                               // type
		X:             floatPtr(100.0),                                 // x (float)
		Y:             floatPtr(200.0),                                 // y (float)
		Width:         floatPtr(100.0),                                 // width (float)
		Height:        floatPtr(100.0),                                 // height (float)
		DSS:           intPtr(DSS_YES),                                 // Document Security Store for LTV Support
	})

  // Example usage of Verify PDF
	verifier, _ := SignPDFKitVerify(libDir)
	verificationResult := verifier.Verify(
    "input/signed_document.pdf"                                     // input pdf
  )
}



const {
  Visibility,
  Subfilter,
  SignatureType,
  DSS,
  SignPDFKitSign,
  SignPDFKitVerify,
} = require("./signpdfkit"); // the wrapper class

const options = {
  email: "user@signpdfkit.com",
  passphrase: "123456",
};

// Location of shared library
const libDir = 'path/to/shared/lib';    // Change this to your actual lib directory path

// Equivalent of PHP's sign_digest_function
async function signDigestFunction(digest, optionsParams) {
// You can provide the cms here by sign the digest
// in this example is using SignPDFKit CMS Generator

  const url = "https://signpdfkit.com/api/sign";
  const payload = {
    digest,
    email: optionsParams.email,
    passphrase: optionsParams.passphrase,
  };

  const res = await fetch(url, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(payload),
  });

  if (!res.ok) {
    const text = await res.text();
    throw new Error(`HTTP Error: ${res.status} - ${text}`);
  }

  const data = await res.json();
  if (!data.cms) {
    throw new Error("Invalid response: " + JSON.stringify(data));
  }

  return data.cms;
}

(async () => {
  try {
    // Example usage of Sign PDF
    const signer = new SignPDFKitSign(libDir, signDigestFunction, options);

    const result = await signer.sign_pdf({
      input_path: "input/sample.pdf",               // input pdf
      output_path: "output/signed.pdf",             // output pdf
      image_path: "input/visualization.png",        // visualization image
      url: "https://signpdfkit.com/file/1234567",   // url for qrcode
      location: "Jakarta",                          // location
      reason: "Need to Approve",                    // reason
      contact_info: "karyadi.dk@gmail.com",         // contact info
      field_id: "SignPDFKit",                       // field id
      character: "#",                               // Character
      signature_type: SignatureType.SIGNATURE,      // signature type
      page: 1,                                      // page
      field_type: Subfilter.ADBE,                   // is pades
      visibility: Visibility.VISIBLE_IMAGE,         // type
      x: 100.0,                                     // x (float)
      y: 200.0,                                     // y (float)
      width: 100.0,                                 // width (float)
      height: 100.0,                                // height (float)
      dss: DSS.YES                                  // Document Security Store for LTV Support
  });

    console.log(result);

  } catch (err) {
    console.error("Error:", err.message);
  }

  // Example usage of Verify PDF
  try {
    const verifier = new SignPDFKitVerify(libDir);
    const verifyResult = verifier.verify(
      "input/signed_document.pdf"                    // input pdf
    );
  } catch (err) {
    console.error("Verification error:", err.message);
  }
})();

require_relative './signpdfkit'  # the wrapper class
require 'json'
require 'base64'
require 'net/http'
require 'uri'

# Location of shared library
LIB_DIR = "path/to/shared/lib"  # Change this to your actual lib directory path

options = {
  "email" => "user@signpdfkit.com",
  "passphrase" => "123456"
}

def sign_digest_function(digest, options_params)
# You can provide the cms here by sign the digest
# in this example is using SignPDFKit CMS Generator

  # 1) Send POST request to PHP API
  url = "https://signpdfkit.com/api/sign"
  uri = URI.parse(url)
  
  headers = {"Content-Type" => "application/json"}
  payload = {
    "digest" => digest,
    "email" => options_params["email"],
    "passphrase" => options_params["passphrase"]
  }

  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = (uri.scheme == "https")
  
  request = Net::HTTP::Post.new(uri.request_uri, headers)
  request.body = payload.to_json

  response = http.request(request)
  
  # Raise error if not 2xx
  unless response.code.start_with?('2')
    raise "HTTP Error: #{response.code} - #{response.body}"
  end

  # 2) Parse JSON response from PHP
  data = JSON.parse(response.body)

  unless data.key?("cms")
    raise "Invalid response: #{data}"
  end

  data["cms"]
end

# Example usage of Sign PDF
signer = SignPDFKitSign.new(LIB_DIR, method(:sign_digest_function), options)

result = signer.sign_pdf(
  input_path = "input/sample.pdf",                # input pdf
  output_path = "output/signed.pdf",              # output pdf
  image_path = "input/visualization.png",         # visualization image
  url = "https://signpdfkit.com/file/1234567",    # url for qrcode
  location = "Jakarta",                           # location
  reason = "Need to Approve",                     # reason
  contact_info = "karyadi.dk@gmail.com",          # contact info
  field_id = "SignPDFKit",                        # field id
  character = "#",                                # Character
  signature_type = SignatureType::SIGNATURE,      # signature type
  page = 1,                                       # page
  field_type = Subfilter::ADBE,                   # is pades
  visibility = Visibility::VISIBLE_IMAGE,         # type
  x = 100.0,                                      # x (float)
  y = 200.0,                                      # y (float)
  width = 100.0,                                  # width (float)
  height = 100.0,                                 # height (float)
  dss = DSS::YES                                  # Document Security Store for LTV Support
)

# Example usage of Verify PDF
verifier = SignPDFKitVerify.new(LIB_DIR)
result = verifier.verify(
  "input/signed_document.pdf"                     # input pdf
)

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.signpdfkit.SignPDFKit.DSS;
import com.signpdfkit.SignPDFKit.Sign;
import com.signpdfkit.SignPDFKit.SignatureType;
import com.signpdfkit.SignPDFKit.Subfilter;
import com.signpdfkit.SignPDFKit.Visibility;
import com.signpdfkit.SignPDFKit.Verify;
import com.signpdfkit.SignPDFKit.Sign.SignPdfOptions;

public class Main {

    // Example usage
    public static void main(String[] args) {
        // Example usage

        BiFunction<String, Map<String, Object>, String> signFunction = (digest, options) -> {
        // You can provide the cms here by sign the digest
        // in this example is using SignPDFKit CMS Generator
        
            try {

                // API endpoint
                String url = "https://signpdfkit.com/api/sign";

                // Build payload
                ObjectMapper mapper = new ObjectMapper();
                String jsonPayload = mapper.writeValueAsString(Map.of(
                        "digest", digest,
                        "email", options.get("email"),
                        "passphrase", options.get("passphrase")
                ));

                // Build request
                HttpClient client = HttpClient.newHttpClient();
                HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create(url))
                        .header("Content-Type", "application/json")
                        .POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
                        .build();

                // Send request
                HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

                if (response.statusCode() < 200 || response.statusCode() >= 300) {
                    throw new RuntimeException("HTTP Error: " + response.statusCode() + " - " + response.body());
                }

                // Parse JSON response
                Map<String, Object> data = mapper.readValue(response.body(), Map.class);

                if (!data.containsKey("cms")) {
                    throw new RuntimeException("Invalid response: " + response.body());
                }

                return data.get("cms").toString();

            } catch (Exception e) {
                throw new RuntimeException("Error signing digest", e);
            }
        };

        Map<String, Object> options = new HashMap<>();
        options.put("email", "user@signpdfkit.com");
        options.put("passphrase", "123456");

        // Location of shared library
        String libDir = "path/to/shared/lib"  // Change this to your actual lib directory path

        SignPdfOptions signerOptions = new SignPdfOptions(
            "input/sample.pdf",                       // input pdf
            "output/signed.pdf"                       // output pdf
        )
        .imagePath("input/visualization.png")         // visualization image
        .url("https://signpdfkit.com/file/1234567")   // url for qrcode
        .location("Jakarta")                          // location
        .reason("Need to Sign")                       // reason
        .contactInfo("user@signpdfkit.com")           // contact info
        .fieldId("SignPDFKit")                        // field id
        .character("#")                               // Character
        .signatureType(SignatureType.SIGNATURE)       // signature type
        .page(1)                                      // page
        .fieldType(Subfilter.PADES)                   // is pades
        .visibility(Visibility.INVISIBLE)             // type
        .x(100.0)                                     // x (float)
        .y(100.0)                                     // y (float)
        .width(150.0)                                 // width (float)
        .height(50.0)                                 // height (float)
        .dss(DSS.NO);                                 // Document Security Store for LTV Support

        try {
            // Example usage of Sign PDF
            Sign signer = SignPDFKit.createSigner(libDir, signFunction, options);
            String result = signer.signPdf(signerOptions);


            // Example usage of Verify PDF
            Verify verifier = SignPDFKit.createVerifier(libDir);
            String verifyResult = verifier.verify(
              "input/signed_document.pdf"              // input pdf
            );

        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

use std::collections::HashMap;
use reqwest::blocking::Client;
use serde_json::Value;
use anyhow::{anyhow, Result};

mod signpdfkit; // the wrapper class
use signpdfkit::{SignPDFKitSign, SignPDFKitVerify, SignArgs, SignatureType, Subfilter, Visibility, DSS};

fn sign_digest_function(digest: &str, options: &HashMap<String, String>) -> Result<String> {
// You can provide the cms here by sign the digest
// in this example is using SignPDFKit CMS Generator

    let url = "https://signpdfkit.com/api/sign";

    let client = Client::builder()
        .danger_accept_invalid_certs(true) // allow self-signed certs like PHP's CURLOPT_SSL_VERIFYPEER=false
        .build()?;

    let payload = serde_json::json!({
        "digest": digest,
        "email": options.get("email").cloned().unwrap_or_default(),
        "passphrase": options.get("passphrase").cloned().unwrap_or_default(),
    });

    let res = client
        .post(url)
        .json(&payload)
        .send()?;

    if !res.status().is_success() {
        return Err(anyhow!("HTTP Error: {} - {:?}", res.status(), res.text()?));
    }

    let json: Value = res.json()?;
    if let Some(cms) = json.get("cms").and_then(|v| v.as_str()) {
        Ok(cms.to_string())
    } else {
        Err(anyhow!("Invalid response: {:?}", json))
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Location of shared library
    let lib_dir = "path/to/shared/lib";   // Change this to your actual lib directory path

    let mut options = HashMap::new();
    options.insert("email".to_string(), "user@signpdfkit.com".to_string());
    options.insert("passphrase".to_string(), "123456".to_string());

    // Initialize signer
    let signer = SignPDFKitSign::new(
        lib_dir,
        |digest, opts| sign_digest_function(digest, opts),
        options,
    )?;

    // Example usage of Sign PDF
    let args = SignArgs {
        input_path: "input/sample.pdf".to_string(),               // input pdf
        output_path: "output/signed.pdf".to_string(),             // output pdf
        image_path: "input/visualization.png".to_string(),        // visualization image
        url: "https://signpdfkit.com/file/1234567".to_string(),   // url for qrcode
        location: "Jakarta".to_string(),                          // location
        reason: "Need to sign".to_string(),                       // reason
        contact_info: "signpdfkit@gmail.com".to_string(),         // contact info
        field_id: "SignPDFKit".to_string(),                       // field id
        character: "#".to_string(),                               // Character
        signature_type: SignatureType::Signature,                 // signature type
        page: 1,                                                  // page
        field_type: Subfilter::Adbe,                              // is pades
        visibility: Visibility::Invisible,                        // type
        x: 0.0,                                                   // x (float)
        y: 0.0,                                                   // y (float)
        width: 50.0,                                              // width (float)
        height: 50.0,                                             // height (float)
        dss: DSS::Yes,                                            // Document Security Store for LTV Support
    };
    let result = signer.sign_pdf(args)?;


    // Example usage of Verify PDF
    let verifier = SignPDFKitVerify::new(lib_dir)?;
    let verify_result = verifier.verify(
      "input/signed_document.pdf"                                 // input pdf
    )?;

    Ok(())
}


// Coming Soon

// Coming Soon

// Coming Soon

// Coming Soon