Digital PDF signing API for developers
Add digital certificate signatures to any PDF with a single API call. Built for developers who need reliable PDF signing, with multi-sign support, metadata control, and certificate validation — all without managing servers or cryptography libraries.
Works with any technology
Features
Everything you need to add digital signatures to your application, nothing you don't.
Free tier included
Start with a generous free plan — no credit card required. Upgrade only when your volume grows, with transparent pricing that scales with your business.
Fast integration
Go from zero to signed PDFs in minutes. Our clean REST API and SDKs for popular languages mean you spend less time on setup and more time shipping features.
Developer-first
Built for developers who value clean APIs. Straightforward endpoints, predictable responses, and comprehensive docs so your team can integrate with confidence.
Built to scale
Whether you sign ten documents a day or ten thousand, our infrastructure handles the load. Auto-scaling, high availability, and consistent low-latency responses.
Enterprise-grade security
Your certificates and documents are never stored. All data is processed in memory with end-to-end encryption. Fully compliant with industry security standards.
Dedicated support
Real humans, fast responses. Reach our engineering team directly via email whenever you need help — no ticket queues, no chatbots.
Simple pricing for every team
Start free, scale as you grow. No hidden fees.
- Daily Signatures:5
- Monthly Signatures:10
- API Credentials:1
- API Sign PDF
- API Signature Customization
- API Signature Background Customization
- Daily Signatures:100
- Monthly Signatures:10,000
- API Credentials:3
- API Sign PDF
- API Signature Customization
- API Signature Background Customization
- Daily Signatures:UNLIMITED
- Monthly Signatures:UNLIMITED
- API Credentials:UNLIMITED
- API Sign PDF
- API Signature Customization
- API Signature Background Customization
Code examples
Copy-paste ready examples in your favorite language.
PDF Signing
Sign PDFs with digital certificates via API.
import axios from "axios";
import * as fs from "fs";
async function signPdf(response) {
// Read the digital certificate file (can be .pfx or .p12 format)
const cert = fs.readFileSync("certificate.pfx");
// Read the PDF document to be signed
const pdf = fs.readFileSync("document.pdf");
// Read the custom background image (optional, used for payment accounts)
// If you have a free account, you can use the default background and
// upload a logo separately using the "signatureImage" parameter.
const backgroundImage = fs.readFileSync("logo.png");
// Import FormData for constructing the form data (not needed in client-side JavaScript)
const FormData = require("form-data");
const formData = new FormData();
// Append the digital certificate to the form data
formData.append("certificate", cert, {
filename: "certificate.pfx",
contentType: "application/x-pkcs12",
});
// Append the password for the digital certificate
formData.append("certificatePassword", "password");
// Append the PDF document to the form data
formData.append("pdf", pdf, {
filename: "pdf.pdf",
contentType: "application/pdf",
});
// Append the custom background image to the form data (optional)
formData.append("signatureBackgroundImage", backgroundImage, {
filename: "logo.png",
contentType: "image/png",
});
// Optional: Modify PDF metadata (e.g., author, title, keywords)
formData.append("pdfMetadataAuthor", "AUTHOR"); // PDF author
formData.append("pdfMetadataKeywords", "keywords,keyword2"); // PDF keywords
formData.append("pdfMetadataTitle", "MY DOCUMENT"); // PDF title
formData.append("pdfMetadataSubject", "EXAMPLE DOCUMENT"); // PDF subject
formData.append("pdfMetadataCreator", "PDFSIGNIFY"); // PDF creator software
formData.append("pdfMetadataProducer", "PDFSIGNIFY"); // PDF producer software
formData.append("pdfMetadataCreationDate", new Date().toLocaleString()); // Creation date
formData.append("pdfMetadataModificationDate", new Date().toLocaleString()); // Modification date
// Customize signature appearance and position
formData.append("signaturePageAppearance", -1); // Page number for signature (-1 for all pages or specify an array of pages)
formData.append("timezone", "UTC"); // Timezone for signature date and time
formData.append("signatureMessage", "Digitally signed by the user"); // Reason/message for the signature
formData.append("signatureDateLabel", ""); // Label for the signature date (empty string for no label)
formData.append("signatureDateFormat", "Y-m-d H:i:s"); // Format for the signature date
formData.append("signatureHeight", 100); // Signature height in pixels
formData.append("signatureWidth", 150); // Signature width in pixels
formData.append("signatureYPosition", 100); // Y position of the signature relative to the bottom of the page
formData.append("signatureXPosition", 180); // X position of the signature relative to the left of the page
// Send the request to sign the PDF document
try {
// Make a POST request using axios with form data
const res = await axios.post("https://api.pdfsignify.com/api/v1/sign-pdf", formData, {
headers: {
contentType: "multipart/form-data", // Important: set content type to "multipart/form-data"
"AccessKey": "MY_ACCESS_KEY", // Your access key for the API
"SecretKey": "MY_SECRET_KEY" // Your secret key for the API
},
responseType: "arraybuffer" // The response will be in arrayBuffer format to handle the returned PDF
});
// Send the signed PDF as a response
response.contentType("application/pdf");
return response.send(res.data);
} catch (error) {
// Log any errors and return the error object
console.error(error);
return error;
}
}PDF Metadata
Read and modify PDF metadata programmatically.
import axios from "axios";
import * as fs from "fs";
async function setMetadata(response) {
// Read the PDF document to be signed
const pdf = fs.readFileSync("document.pdf");
// Import FormData for constructing the form data (not needed in client-side JavaScript)
const FormData = require("form-data");
const formData = new FormData();
// Append the PDF document to the form data
formData.append("pdf", pdf, {
filename: "pdf.pdf",
contentType: "application/pdf",
});
// Modify PDF metadata (e.g., author, title, keywords)
formData.append("pdfMetadataAuthor", "AUTHOR"); // PDF author
formData.append("pdfMetadataKeywords", "keywords,keyword2"); // PDF keywords
formData.append("pdfMetadataTitle", "MY DOCUMENT"); // PDF title
formData.append("pdfMetadataSubject", "EXAMPLE DOCUMENT"); // PDF subject
formData.append("pdfMetadataCreator", "PDFSIGNIFY"); // PDF creator software
formData.append("pdfMetadataProducer", "PDFSIGNIFY"); // PDF producer software
formData.append("pdfMetadataCreationDate", new Date().toLocaleString()); // Creation date
formData.append("pdfMetadataModificationDate", new Date().toLocaleString()); // Modification date
try {
const res = await axios.post("https://api.pdfsignify.com/api/v1/set-pdf-metadata", formData, {
headers: {
contentType: "multipart/form-data", // Important: set content type to "multipart/form-data"
"AccessKey": "MY_ACCESS_KEY", // Your access key for the API
"SecretKey": "MY_SECRET_KEY" // Your secret key for the API
},
responseType: "arraybuffer" // The response will be in arrayBuffer format to handle the returned PDF
});
response.contentType("application/pdf");
return response.send(res.data);
} catch (error) {
console.error(error);
return error;
}
}Certificate Validation
Validate certificate integrity and password.
import axios from "axios";
import * as fs from "fs";
async function checkCertificatePassword(response) {
// Read the digital certificate file (can be .pfx or .p12 format)
const cert = fs.readFileSync("certificate.pfx");
// Import FormData for constructing the form data (not needed in client-side JavaScript)
const FormData = require("form-data");
const formData = new FormData();
// Append the digital certificate to the form data
formData.append("certificate", cert, {
filename: "certificate.pfx",
contentType: "application/x-pkcs12",
});
// Append the password for the digital certificate
formData.append("certificatePassword", "password");
try {
// Send a POST request to check the certificate password
const res = await axios.post("https://api.pdfsignify.com/api/v1/check-certificate-password", formData, {
headers: {
contentType: "multipart/form-data", // Important: set content type to "multipart/form-data"
"AccessKey": "MY_ACCESS_KEY", // Your access key for the API
"SecretKey": "MY_SECRET_KEY" // Your secret key for the API
},
});
// Send the result of the password check (success or failure) as a response
return response.send(res.data.success);
} catch (error) {
// Log any errors and return the error object
console.error(error);
return response.send(error);
}
}
PDF Signing
Sign PDFs with digital certificates via API.
<?php
// Read the digital certificate file (can be .pfx or .p12 format)
$cert = file_get_contents('certificate.pfx');
// Read the PDF document to be signed
$pdf = file_get_contents('document.pdf');
// Read the custom background image (optional)
$backgroundImage = file_get_contents('logo.png');
// Prepare the form data
$boundary = uniqid();
$delimiter = '--------------------' . $boundary;
$data = [];
// Add certificate
$data[] = '--' . $delimiter;
$data[] = 'Content-Disposition: form-data; name="certificate"; filename="certificate.pfx"';
$data[] = 'Content-Type: application/x-pkcs12';
$data[] = '';
$data[] = $cert;
// Add certificate password
$data[] = '--' . $delimiter;
$data[] = 'Content-Disposition: form-data; name="certificatePassword"';
$data[] = '';
$data[] = 'password';
// Add PDF document
$data[] = '--' . $delimiter;
$data[] = 'Content-Disposition: form-data; name="pdf"; filename="document.pdf"';
$data[] = 'Content-Type: application/pdf';
$data[] = '';
$data[] = $pdf;
// Add custom background image
$data[] = '--' . $delimiter;
$data[] = 'Content-Disposition: form-data; name="signatureBackgroundImage"; filename="logo.png"';
$data[] = 'Content-Type: image/png';
$data[] = '';
$data[] = $backgroundImage;
// Add PDF metadata
$metadata = [
'pdfMetadataAuthor' => 'AUTHOR',
'pdfMetadataKeywords' => 'keywords,keyword2',
'pdfMetadataTitle' => 'MY DOCUMENT',
'pdfMetadataSubject' => 'EXAMPLE DOCUMENT',
'pdfMetadataCreator' => 'PDFSIGNIFY',
'pdfMetadataProducer' => 'PDFSIGNIFY',
'pdfMetadataCreationDate' => date('Y-m-d H:i:s'),
'pdfMetadataModificationDate' => date('Y-m-d H:i:s'),
];
foreach ($metadata as $key => $value) {
$data[] = '--' . $delimiter;
$data[] = 'Content-Disposition: form-data; name="' . $key . '"';
$data[] = '';
$data[] = $value;
}
// Add signature customization
$signatureCustomization = [
'signaturePageAppearance' => '-1',
'timezone' => 'UTC',
'signatureMessage' => 'Digitally signed by the user',
'signatureDateLabel' => '',
'signatureDateFormat' => 'Y-m-d H:i:s',
'signatureHeight' => '100',
'signatureWidth' => '150',
'signatureYPosition' => '100',
'signatureXPosition' => '180',
];
foreach ($signatureCustomization as $key => $value) {
$data[] = '--' . $delimiter;
$data[] = 'Content-Disposition: form-data; name="' . $key . '"';
$data[] = '';
$data[] = $value;
}
// End boundary
$data[] = '--' . $delimiter . '--';
$data[] = '';
// Convert the data array to a string
$postData = implode("\r\n", $data);
// Initialize cURL
$ch = curl_init('https://api.pdfsignify.com/api/v1/sign-pdf');
// Set cURL options
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: multipart/form-data; boundary=' . $delimiter,
'AccessKey: MY_ACCESS_KEY', // Your access key for the API
'SecretKey: MY_SECRET_KEY' // Your secret key for the API
]);
// Execute cURL request
$response = curl_exec($ch);
// Check for cURL errors
if ($response === false) {
echo 'cURL Error: ' . curl_error($ch);
} else {
// Check if the response is a PDF
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
if (strpos($contentType, 'application/pdf') !== false) {
// Set the correct headers for PDF output
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="signed_document.pdf"');
echo $response;
} else {
echo 'Error: Expected PDF response, got ' . $contentType;
}
}
// Close cURL session
curl_close($ch);
exit();PDF Metadata
Read and modify PDF metadata programmatically.
<?php
// Read the PDF document to be signed
$pdf = file_get_contents('document.pdf');
// Prepare the form data
$boundary = uniqid();
$delimiter = '--------------------' . $boundary;
$data = [];
// Add PDF document
$data[] = '--' . $delimiter;
$data[] = 'Content-Disposition: form-data; name="pdf"; filename="document.pdf"';
$data[] = 'Content-Type: application/pdf';
$data[] = '';
$data[] = $pdf;
// Add PDF metadata
$metadata = [
'pdfMetadataAuthor' => 'AUTHOR',
'pdfMetadataKeywords' => 'keywords,keyword2',
'pdfMetadataTitle' => 'MY DOCUMENT',
'pdfMetadataSubject' => 'EXAMPLE DOCUMENT',
'pdfMetadataCreator' => 'PDFSIGNIFY',
'pdfMetadataProducer' => 'PDFSIGNIFY',
'pdfMetadataCreationDate' => date('Y-m-d H:i:s'),
'pdfMetadataModificationDate' => date('Y-m-d H:i:s'),
];
foreach ($metadata as $key => $value) {
$data[] = '--' . $delimiter;
$data[] = 'Content-Disposition: form-data; name="' . $key . '"';
$data[] = '';
$data[] = $value;
}
// End boundary
$data[] = '--' . $delimiter . '--';
$data[] = '';
// Convert the data array to a string
$postData = implode("\r\n", $data);
// Initialize cURL
$ch = curl_init('https://api.pdfsignify.com/api/v1/set-pdf-metadata');
// Set cURL options
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: multipart/form-data; boundary=' . $delimiter,
'AccessKey: MY_ACCESS_KEY', // Your access key for the API
'SecretKey: MY_SECRET_KEY' // Your secret key for the API
]);
// Execute cURL request
$response = curl_exec($ch);
// Check for cURL errors
if ($response === false) {
echo 'cURL Error: ' . curl_error($ch);
} else {
// Check if the response is a PDF
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
if (strpos($contentType, 'application/pdf') !== false) {
// Set the correct headers for PDF output
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="signed_document.pdf"');
echo $response;
} else {
echo 'Error: Expected PDF response, got ' . $contentType;
}
}
// Close cURL session
curl_close($ch);
exit();Certificate Validation
Validate certificate integrity and password.
<?php
// Read the digital certificate file (can be .pfx or .p12 format)
$cert = file_get_contents('certificate.pfx');
// Prepare the form data
$boundary = uniqid();
$delimiter = '--------------------' . $boundary;
$data = [];
// Add certificate
$data[] = '--' . $delimiter;
$data[] = 'Content-Disposition: form-data; name="certificate"; filename="certificate.pfx"';
$data[] = 'Content-Type: application/x-pkcs12';
$data[] = '';
$data[] = $cert;
// Add certificate password
$data[] = '--' . $delimiter;
$data[] = 'Content-Disposition: form-data; name="certificatePassword"';
$data[] = '';
$data[] = 'password';
// End boundary
$data[] = '--' . $delimiter . '--';
$data[] = '';
// Convert the data array to a string
$postData = implode("\r\n", $data);
// Initialize cURL
$ch = curl_init('https://api.pdfsignify.com/api/v1/check-certificate-password');
// Set cURL options
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: multipart/form-data; boundary=' . $delimiter,
'AccessKey: MY_ACCESS_KEY', // Your access key for the API
'SecretKey: MY_SECRET_KEY' // Your secret key for the API
]);
// Execute cURL request
$response = curl_exec($ch);
// Check for cURL errors
if ($response === false) {
echo 'cURL Error: ' . curl_error($ch);
} else {
echo $response;
}
// Close cURL session
curl_close($ch);
exit();PDF Signing
Sign PDFs with digital certificates via API.
import requests
# Define file paths and credentials
CERT_FILE = "certificate.pfx" # Path to the certificate file
PDF_FILE = "filepdf.pdf" # Path to the PDF file
CERT_PASSWORD = "your_certificate_password" # Replace with your certificate password
# Read files
with open(CERT_FILE, "rb") as cert_file, open(PDF_FILE, "rb") as pdf_file:
cert_data = cert_file.read()
pdf_data = pdf_file.read()
# API endpoint and credentials
API_URL = "https://api.pdfsignify.com/api/v1/sign-pdf"
ACCESS_KEY = "MY_ACCESS_KEY" # Replace with your access key
SECRET_KEY = "MY_SECRET_KEY" # Replace with your secret key
# Prepare the form data
files = {
"certificate": ("certificate.pfx", cert_data, "application/x-pkcs12"),
"pdf": ("filepdf.pdf", pdf_data, "application/pdf"),
}
data = {"certificatePassword": CERT_PASSWORD}
headers = {
"AccessKey": ACCESS_KEY,
"SecretKey": SECRET_KEY,
}
try:
# Send the POST request
response = requests.post(API_URL, headers=headers, files=files, data=data)
# Check if the request was successful
if response.status_code == 200:
# Save the signed PDF
with open("signed_document.pdf", "wb") as signed_pdf:
signed_pdf.write(response.content)
print("PDF signed successfully! Saved as 'signed_document.pdf'")
else:
print(f"Failed to sign PDF: {response.status_code}")
print(f"Response: {response.text}")
except Exception as e:
print(f"An error occurred: {e}")PDF Metadata
Read and modify PDF metadata programmatically.
import requests
import datetime
# Define file paths and credentials
PDF_FILE = "document.pdf" # Path to the PDF file
ACCESS_KEY = "MY_ACCESS_KEY" # Replace with your API access key
SECRET_KEY = "MY_SECRET_KEY" # Replace with your API secret key
API_URL = "https://api.pdfsignify.com/api/v1/set-pdf-metadata" # API endpoint
# Read the PDF file
with open(PDF_FILE, "rb") as pdf_file:
pdf_data = pdf_file.read()
# Prepare metadata for the PDF
metadata = {
"pdfMetadataAuthor": "AUTHOR",
"pdfMetadataKeywords": "keywords,keyword2",
"pdfMetadataTitle": "MY DOCUMENT",
"pdfMetadataSubject": "EXAMPLE DOCUMENT",
"pdfMetadataCreator": "PDFSIGNIFY",
"pdfMetadataProducer": "PDFSIGNIFY",
"pdfMetadataCreationDate": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"pdfMetadataModificationDate": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
}
# Construct the files and data dictionaries for the request
files = {
"pdf": ("document.pdf", pdf_data, "application/pdf"),
}
# Add metadata as form data
data = metadata
# Set headers for the request
headers = {
"AccessKey": ACCESS_KEY,
"SecretKey": SECRET_KEY,
}
# Send the request
try:
response = requests.post(API_URL, headers=headers, files=files, data=data)
# Check the response
if response.status_code == 200:
# Check if the response is a PDF
content_type = response.headers.get("Content-Type", "")
if "application/pdf" in content_type:
# Save the signed PDF
with open("signed_document.pdf", "wb") as signed_pdf:
signed_pdf.write(response.content)
print("PDF metadata set successfully! Saved as 'signed_document.pdf'")
else:
print(f"Error: Expected PDF response, got {content_type}")
print("Response:", response.text)
else:
print(f"Failed to set PDF metadata: {response.status_code}")
print("Response:", response.text)
except Exception as e:
print(f"An error occurred: {e}")
Certificate Validation
Validate certificate integrity and password.
import requests
# Define file paths and credentials
CERT_FILE = "certificate.pfx" # Path to the certificate file
CERT_PASSWORD = "your_certificate_password" # Replace with your certificate password
# Read files
with open(CERT_FILE, "rb") as cert_file:
cert_data = cert_file.read()
# API endpoint and credentials
API_URL = "https://api.pdfsignify.com/api/v1/check-certificate-password"
ACCESS_KEY = "MY_ACCESS_KEY" # Replace with your access key
SECRET_KEY = "MY_SECRET_KEY" # Replace with your secret key
# Prepare the form data
files = {
"certificate": ("certificate.pfx", cert_data, "application/x-pkcs12"),
}
# Add required parameters
data = {"certificatePassword": CERT_PASSWORD}
# API Headers with keys
headers = {
"AccessKey": ACCESS_KEY,
"SecretKey": SECRET_KEY,
}
try:
# Send the POST request
response = requests.post(API_URL, headers=headers, files=files, data=data)
# Check if the request was successful
if response.status_code == 200:
print("Certificate validity and password check successful.")
print("Response Data:", response.json())
else:
print(f"Error: {response.status_code}")
print("Response Data:", response.text)
except Exception as e:
print(f"An error occurred: {e}")Tutorials
Step-by-step guides to get you up and running.
Frequently asked questions
Have more questions? Reach us at Email.
Get in touch
Questions, feedback, or partnership inquiries?
We respond to every message within 24 hours.
Ready to start signing?
Skip the infrastructure setup. Integrate our API and ship signed documents in minutes, not weeks.