This document provides a comprehensive overview of the essential steps for creating and customizing PDF reports, setting up report generation, handling webhooks, and managing completed reports.

Introduction

The PDF API allows you to generate detailed and customizable PDF reports of scan results, including plagiarism checks, AI detection, and Grammar Checker feedback. These reports can be branded with your own logo and customized to match your organization’s needs. The PDF generation process is integrated with the Copyleaks scanning process, where you enable PDF creation during scan submission and then receive the generated PDF through webhooks. Copyleaks API also offers different PDF report versions, with version 3 being the latest and most feature-rich option that includes advanced formatting and comprehensive analysis visualization.
PDF files for keeping records of individual scan results, which complement the interactive reports, are created through the download functionality in the report UI. If you have other PDF requirements to complement the interactive report options, please contact Copyleaks Support.

Before you begin

Before you start using the PDF API, ensure you have the following:
  1. An active Copyleaks account: If you don’t have one, sign up here.
  2. Familiarity with RESTful API principles: Basic knowledge of HTTP requests and responses.
  3. A tool for HTTP requests: Use tools like cURL, Postman, or Copyleaks’ SDK.

Installations

Choose your preferred method for making API calls.
# macOS
brew install curl

# Ubuntu/Debian
sudo apt-get install curl

# Windows - download from https://curl.se
pip install copyleaks
npm install plagiarism-checker
Install-Package Copyleaks
composer require copyleaks/php-plagiarism-checker
gem install plagiarism-checker
<!-- Add to your pom.xml (requires Java 11+) -->
<dependency>
    <groupId>com.copyleaks.sdk</groupId>
    <artifactId>copyleaks-java-sdk</artifactId>
    <version>5.1.0</version>
</dependency>
HTTP needs no installation - call the API with any standard HTTP client, or import our Postman collection for a quicker start.

Login

To enable PDF report generation, we first need to generate an access token. We will use the login endpoint. The API key can be found on the Copyleaks API Dashboard. Upon successful authentication, you will receive a token that must be attached to subsequent API calls via the Authorization: Bearer <TOKEN> header. This token remains valid for 48 hours.
To boost performance, cache your login token and reuse it for all requests. The token remains valid for up to 48 hours, so you don’t need to log in repeatedly. The login method has stricter rate limits than other endpoints.
POST https://id.copyleaks.com/v3/account/login/api
Content-Type: application/json

{
    "email": "<EMAIL_ADDRESS>",
    "key": "<API_KEY>"
}
curl -X POST "https://id.copyleaks.com/v3/account/login/api" \
     -H "Content-Type: application/json" \
     -d '{
           "email": "<EMAIL_ADDRESS>",
           "key": "<API_KEY>"
         }'
from copyleaks.copyleaks import Copyleaks
from copyleaks.exceptions.command_error import CommandError
from copyleaks.models.submit.document import FileDocument
from copyleaks.models.submit.properties.scan_properties import ScanProperties
from copyleaks.models.export import Export, ExportCrawledVersion, ExportResult, ExportPDF
import base64
import random

EMAIL_ADDRESS = "<EMAIL_ADDRESS>"
API_KEY = "<API_KEY>"

# Login to Copyleaks
try:
    auth_token = Copyleaks.login(EMAIL_ADDRESS, API_KEY)
except CommandError as ce:
    response = ce.get_response()
    print(f"An error occurred (HTTP status code {response.status_code}):")
    print(response.content)
    exit(1)

print("Logged successfully!\nToken:")
print(auth_token)
const copyleaks = require('copyleaks');

const EMAIL_ADDRESS = "<EMAIL_ADDRESS>";
const API_KEY = "<API_KEY>";

// Login to Copyleaks
const login = async () => {
    try {
        const authToken = await copyleaks.login(EMAIL_ADDRESS, API_KEY);
        console.log('Logged successfully!\nToken:', authToken);
        return authToken;
    } catch (error) {
        console.error('Failed to login:', error);
        process.exit(1);
    }
};
import com.copyleaks.sdk.api.Copyleaks;
import com.copyleaks.sdk.api.exceptions.CommandException;
import com.copyleaks.sdk.api.models.ScanProperties;
import com.copyleaks.sdk.api.models.FileSubmission;
import com.copyleaks.sdk.api.models.Export;
import com.copyleaks.sdk.api.models.ExportCrawledVersion;
import com.copyleaks.sdk.api.models.ExportResult;
import com.copyleaks.sdk.api.models.ExportPDF;
import java.util.Base64;
import java.util.Arrays;

String EMAIL_ADDRESS = "<EMAIL_ADDRESS>";
String API_KEY = "<API_KEY>";

// Login to Copyleaks
try {
    String authToken = Copyleaks.login(EMAIL_ADDRESS, API_KEY);
    System.out.println("Logged successfully!\nToken: " + authToken);
} catch (CommandException e) {
    System.out.println("Failed to login: " + e.getMessage());
    System.exit(1);
}

Submit Scan with PDF Report Enabled

Use the submit file endpoint to send content for analysis while enabling PDF report generation. The key difference for PDF reports is including the properties.pdf.create parameter set to true. In the URL, supply your chosen scan ID, which serves as the identifier for the scan. Each scan needs to have a unique scan ID. The properties.pdf.reportVersion should be set to “latest” to use the latest PDF report format with enhanced visuals and comprehensive data visualization. The properties.pdf.title allows you to customize the title that appears on the PDF report. The properties.displayLanguage allows you to generate the PDF report in a specific language. For branding purposes, you can include your organization’s logo using properties.pdf.largeLogo (PNG format, base64 encoded, max 100kb, recommended size 185x50px).
There are more customization options available for PDF reports, but this guide doesn’t cover all of them.For this tutorial, we also pass in properties.sandbox as TRUE to enable sandbox mode. The sandbox mode is free to use, but it returns mock results. Using sandbox mode while working on integrating with the Copyleaks API is helpful.
PUT https://api.copyleaks.com/v3/scans/submit/file/<SCAN_ID>
Authorization: Bearer <your_token>
Content-Type: application/json

{
    "base64": "<base64_encoded_file_content>",
    "filename": "<FILE_NAME>",
    "properties": {
        "webhooks": { "status": "https://your.server/webhook?event={\{STATUS\}}" },
        "sandbox": true,
        "pdf": {
            "create": true,
            "reportVersion": "v3",
            "title": "Custom PDF Report Title",
            "largeLogo": "<base64_encoded_logo>"
        }
    }
}
curl -X PUT "https://api.copyleaks.com/v3/scans/submit/file/<SCAN_ID>" \
     -H "Authorization: Bearer <your_token>" \
     -H "Content-Type: application/json" \
     -d '{
           "base64": "<base64_encoded_file_content>",
           "filename": "<FILE_NAME>",
           "properties": {
               "webhooks": { "status": "https://your.server/webhook?event={\{STATUS\}}" },
               "sandbox": true,
               "pdf": {
                   "create": true,
                   "reportVersion": "v3",
                   "title": "Custom PDF Report Title",
                   "largeLogo": "<base64_encoded_logo>"
               }
           }
         }'
# Submit a file for scanning with PDF generation enabled
scan_id = "<SCAN_ID>";
file_name = "<FILE_NAME>"
base64_file_content = base64.b64encode(b'Hello world.').decode('utf8')  # or read your file and convert it into BASE64 presentation.
print("Submitting a new file...")
file_submission = FileDocument(base64_file_content, file_name)

# Set scan properties with PDF options
scan_properties = ScanProperties('https://your.server/webhook?event={\{STATUS\}}')
scan_properties.set_sandbox(True)  # Turn on sandbox mode. Turn off on production.

# Enable PDF report generation
scan_properties.set_pdf({
    "create": True,
    "reportVersion": "v3",
    "title": "Custom PDF Report Title"
    # Add base64_logo if needed
})

file_submission.set_properties(scan_properties)

# Submit the file for scanning
Copyleaks.submit_file(auth_token, scan_id, file_submission)
print("Sent to scanning with PDF report enabled")
print("You will be notified, using your webhook, once the scan is completed.")
// Submit a file for scanning with PDF report enabled
const scanId = "<SCAN_ID>"; // Replace with your unique scan ID
const filename = "<FILE_NAME>";
const fileContent = Buffer.from('Hello world').toString('base64'); // Convert file content to base64

const submitFile = async (authToken) => {
    const scanProperties = new copyleaks.ScanProperties('https://your.server/webhook?event={\{STATUS\}}');
    scanProperties.setSandbox(true); // Enable sandbox mode for testing

    // Enable PDF report generation
    scanProperties.setPDF({
        create: true,
        reportVersion: "v3",
        title: "Custom PDF Report Title"
        // Add largeLogo if needed
    });

    const fileSubmission = new copyleaks.FileSubmission(fileContent, filename);
    fileSubmission.setProperties(scanProperties);

    try {
        await copyleaks.submitFile(authToken, scanId, fileSubmission);
        console.log('File submitted for scanning with PDF report enabled. Scan ID:', scanId);
    } catch (error) {
        console.error('Failed to submit file:', error);
    }
};
// Submit a file for scanning with PDF report enabled
String scanId = "<SCAN_ID>"; // Replace with your unique scan ID
String filename = "<FILE_NAME>";
String fileContent = Base64.getEncoder().encodeToString("Hello world".getBytes()); // Convert file content to base64

ScanProperties scanProperties = new ScanProperties("https://your.server/webhook?event={\{STATUS\}}");
scanProperties.setSandbox(true); // Enable sandbox mode for testing

// Enable PDF report generation
Map<String, Object> pdfProperties = new HashMap<>();
pdfProperties.put("create", true);
pdfProperties.put("reportVersion", "v3");
pdfProperties.put("title", "Custom PDF Report Title");
// Add largeLogo if needed
scanProperties.setPDF(pdfProperties);

FileSubmission fileSubmission = new FileSubmission(fileContent, filename);
fileSubmission.setProperties(scanProperties);

try {
    Copyleaks.submitFile(authToken, scanId, fileSubmission);
    System.out.println("File submitted for scanning with PDF report enabled. Scan ID: " + scanId);
} catch (CommandException e) {
    System.out.println("Failed to submit file: " + e.getMessage());
}

PDF Customization Options

The PDF report can be extensively customized to match your organization’s branding and requirements.
PropertyTypeDescriptionDefault
createbooleanAdd a request to generate a customizable export of the scan report, in a pdf format. Set to true in order to generate a pdf report for this scan.false
titlestringCustomize the title for the PDF report. Maximum 256 characters.null
colorsobjectObject containing color customization options for the PDF report.-
largeLogostring (base64)Customize the logo image in the PDF report. Only supports png format. Max file size: 100kb. Recommended size: width 185px, height 50px.null
rtlbooleanWhen set to true, the text in the report will be aligned from right to left.false
reportVersionstringPDF version to generate. By default latest version will be generated. Version 3 is the latest iteration of the PDF report. Available values: v1, v2, v3, latestlatest

Wait For Scan Completion

The scan and PDF report generation may take seconds to minutes, depending on the content, features used, and products enabled. Once the scan is complete successfully, Copyleaks API will send a completed webhook to the URL you supplied in the submit under properties.webhooks.status. At the same time, the {STATUS} is replaced with “completed”. The completed webhooks hold the summary information about the scan, such as the number of matched words, total words, and results found. If the scan finishes with an error, an error webhook will be sent to the properties.webhooks.status while the {STATUS} is replaced with error.
For testing purposes, we recommend using a third-party service such as request bin or ngrok.

Exporting PDF Reports

Use the export method to retrieve the generated PDF report along with other scan artifacts. The export method sends webhooks with each artifact’s content to your specified target server. We supply the Scan ID we used earlier in the submit endpoint in the URL. The user chooses a unique Export ID for each export. For PDF reports specifically, we add a pdf section to the export request, providing an endpoint where the PDF should be sent when ready.
POST https://api.copyleaks.com/v3/downloads/<SCAN_ID>/export/<EXPORT_ID>
Authorization: Bearer <API_TOKEN>
Content-Type: application/json

{
    "completionWebhook": "https://your.server/webhook/export/completion",
    "pdf": {
        "endpoint": "https://your.server/webhook/export/pdf",
        "verb": "POST",
        "headers": {
            "key": "value",
            "key2": "value2"
        }
    }
}
curl -X POST "https://api.copyleaks.com/v3/downloads/<SCAN_ID>/export/<EXPORT_ID>" \
     -H "Authorization: Bearer <API_TOKEN>" \
     -H "Content-Type: application/json" \
     -d '{
           "completionWebhook": "https://your.server/webhook/export/completion",
           "pdf": {
               "endpoint": "https://your.server/webhook/export/pdf",
               "verb": "POST",
               "headers": {
                   "key": "value",
                   "key2": "value2"
               }
           }
         }'
# Export scan results including PDF report
export_id = "<EXPORT_ID>"
export = Export()
export.set_completion_webhook('https://your.server/webhook/export/completion')

# Export PDF report
pdf_export = ExportPDF()
pdf_export.set_endpoint('https://your.server/webhook/export/pdf')
pdf_export.set_verb('POST')
pdf_export.set_headers([['key', 'value'], ['key2', 'value2']])  # optional
export.set_pdf(pdf_export)

# Trigger the export
Copyleaks.export(auth_token, scan_id, export_id, export)
print("Export initiated. You will be notified via webhook once the export is completed.")
// Export scan results including PDF report
const exportId = '<EXPORT_ID>';
const exportResults = async (authToken, scanId) => {
    const exportRequest = new copyleaks.Export();
    exportRequest.setCompletionWebhook('https://your.server/webhook/export/completion');

    // Export PDF report
    const pdfExport = new copyleaks.ExportPDF();
    pdfExport.setEndpoint('https://your.server/webhook/export/pdf');
    pdfExport.setVerb('POST');
    exportRequest.setPDF(pdfExport);

    try {
        await copyleaks.export(authToken, scanId, exportId, exportRequest);
        console.log('Export initiated with PDF report. Export ID:', exportId);
    } catch (error) {
        console.error('Failed to export results:', error);
    }
};
// Export scan results including PDF report
String exportId = "<EXPORT_ID>";
Export exportRequest = new Export();
exportRequest.setCompletionWebhook("https://your.server/webhook/export/completion");

// Export PDF report
ExportPDF pdfExport = new ExportPDF();
pdfExport.setEndpoint("https://your.server/webhook/export/pdf");
pdfExport.setVerb("POST");
exportRequest.setPDF(pdfExport);

try {
    Copyleaks.export(authToken, scanId, exportId, exportRequest);
    System.out.println("Export initiated with PDF report. Export ID: " + exportId);
} catch (CommandException e) {
    System.out.println("Failed to export results: " + e.getMessage());
}

Next Steps

Webhooks Overview

Learn about webhooks in the Copyleaks API and how to handle real-time notifications.

Export Method

Understand the export method for retrieving various scan artifacts including PDF reports.

Authenticity API Overview

Learn about the comprehensive scanning API that supports multiple products and features.

Support

Should you require any assistance or have inquiries, please contact Copyleaks Support or ask a question on Stack Overflow with the copyleaks-api tag.