← 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

Swift (XCode)

⬇️ SignPDFKit.swift

TypeScript

⬇️ Coming Soon

C++

⬇️ Coming Soon

C#

⬇️ Coming Soon

Dart

⬇️ Coming Soon

⚙️ Setup Instructions

Desktop
Android
iOS
Web

1. Download the SignPDFKit shared library and Extract the archive to your preferred location

2. Download the wrapper according to the programming language and place on the project

3. Call a function by inputting the library path (look at the usage tab)

Note: For macOS specifically, do the command xattr -d com.apple.quarantine path-to/lib/macos_x86_64/libsignpdfkit.dylib && xattr -d com.apple.quarantine path-to/lib/macos_arm64/libsignpdfkit.dylib to grant access to the shared library

// Coming Soon

// Coming Soon

// Coming Soon

📄 Example Usage

Select the programming language to be used


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

options = {
    "email": "user@signpdfkit.com",
    "passcode": "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"],
        "passcode": options_params["passcode"]
    }

    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",
    "passcode" => "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"],
        "passcode" => $options_params["passcode"]
    ];

    $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",
		"passcode": "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"],
			"passcode": options["passcode"],
		}
		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",
  passcode: "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,
    passcode: optionsParams.passcode,
  };

  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",
  "passcode" => "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"],
    "passcode" => options_params["passcode"]
  }

  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"),
                        "passcode", options.get("passcode")
                ));

                // 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("passcode", "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(),
        "passcode": options.get("passcode").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("passcode".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