Java PDF Generation SDK

The official cloudlayerio-java library provides Java PDF generation with builder pattern options, automatic retry logic, and thread-safe clients. Convert HTML to PDF, capture URLs as documents, and render templates — with only Jackson as a runtime dependency.

Installation

Maven

<dependency>
    <groupId>io.cloudlayer</groupId>
    <artifactId>cloudlayerio-java</artifactId>
    <version>0.1.0</version>
</dependency>

Gradle

implementation 'io.cloudlayer:cloudlayerio-java:0.1.0'

Requirements: Java 11+, only Jackson for JSON (no other runtime dependencies)

Setup

Get your API key by creating a free account at cloudlayer.io. Your account comes with free API credits for testing.

import io.cloudlayer.sdk.*;
import io.cloudlayer.sdk.model.endpoint.*;
import io.cloudlayer.sdk.model.constants.*;
import io.cloudlayer.sdk.model.response.*;

CloudLayer client = CloudLayer.builder("YOUR-API-KEY", ApiVersion.V2).build();

The SDK requires you to choose an API version:

v1v2
Default modeSynchronous (returns binary)Asynchronous (returns Job)
Sync responseRaw binary (PDF/image bytes)JSON Job object
Binary accessDirect from result.getBytes()Via downloadJobResult()

URL to PDF

v2 returns a Job object. Use waitForJob() + downloadJobResult() to get the binary:

ConversionResult result = client.urlToPdf(UrlToPdfOptions.builder()
        .url("https://example.com")
        .format(PdfFormat.A4)
        .printBackground(true)
        .build());

Job job = client.waitForJob(result.getJob().getId());
byte[] pdf = client.downloadJobResult(job);
Files.write(Path.of("output.pdf"), pdf);

v1

v1 returns binary directly:

CloudLayer v1Client = CloudLayer.builder("YOUR-API-KEY", ApiVersion.V1).build();

ConversionResult result = v1Client.urlToPdf(UrlToPdfOptions.builder()
        .url("https://example.com")
        .format(PdfFormat.A4)
        .build());

byte[] pdf = result.getBytes();

URL to Image

ConversionResult result = client.urlToImage(UrlToImageOptions.builder()
        .url("https://example.com")
        .imageType(ImageType.PNG)
        .quality(90)
        .build());

Job job = client.waitForJob(result.getJob().getId());
byte[] image = client.downloadJobResult(job);

HTML to PDF

HTML must be Base64-encoded. Use the included HtmlUtil.encodeHtml() helper:

import io.cloudlayer.sdk.util.HtmlUtil;

String html = "<html><body><h1>Hello World</h1></body></html>";

ConversionResult result = client.htmlToPdf(HtmlToPdfOptions.builder()
        .html(HtmlUtil.encodeHtml(html))
        .format(PdfFormat.LETTER)
        .printBackground(true)
        .build());

Template to PDF

ConversionResult result = client.templateToPdf(TemplateToPdfOptions.builder()
        .templateId("your-template-id")
        .data(Map.of(
                "name", "John Doe",
                "invoiceNumber", "INV-001",
                "amount", 1500
        ))
        .build());

Document Conversion

DOCX to PDF

import io.cloudlayer.sdk.util.FileInput;

ConversionResult result = client.docxToPdf(DocxToPdfOptions.builder()
        .file(FileInput.fromPath(Path.of("document.docx")))
        .build());

PDF to DOCX

ConversionResult result = client.pdfToDocx(PdfToDocxOptions.builder()
        .file(FileInput.fromPath(Path.of("document.pdf")))
        .build());

Merge PDFs

ConversionResult result = client.mergePdfs(MergePdfsOptions.builder()
        .batch(Batch.of(List.of(
                "https://example.com/doc1.pdf",
                "https://example.com/doc2.pdf"
        )))
        .build());

Data Management

// Jobs
List<Job> jobs = client.listJobs();
Job job = client.getJob("job-id");

// Assets
List<Asset> assets = client.listAssets();
byte[] data = client.downloadJobResult(job);

// Account
AccountInfo account = client.getAccount();
StatusResponse status = client.getStatus();

// Templates
List<PublicTemplate> templates = client.listTemplates();
PublicTemplate template = client.getTemplate("template-id");

Configuration Options

CloudLayer client = CloudLayer.builder("key", ApiVersion.V2)
        .timeout(Duration.ofSeconds(60))          // request timeout (default: 30s)
        .maxRetries(3)                             // retry count, range [0, 5] (default: 2)
        .userAgent("my-app/1.0")                   // custom user agent
        .headers(Map.of("X-Custom", "value"))      // additional headers
        .httpClient(customHttpClient)              // inject custom java.net.http.HttpClient
        .build();

Error Handling

try {
    client.urlToPdf(options);
} catch (AuthException e) {
    // 401 or 403
} catch (RateLimitException e) {
    // 429 — check e.getRetryAfterSeconds()
} catch (ValidationException e) {
    // Client-side validation error
} catch (ApiException e) {
    // Other HTTP error — e.getStatusCode(), e.getResponseBody()
} catch (TimeoutException e) {
    // Request or poll timeout
} catch (NetworkException e) {
    // Connection failure
}

Working with v2 Results

The recommended v2 workflow:

// 1. Start conversion (returns immediately with pending Job)
ConversionResult result = client.urlToPdf(options);

// 2. Wait for completion (polls every 5s, timeout 5min by default)
Job job = client.waitForJob(result.getJob().getId());

// 3. Download the binary
byte[] pdf = client.downloadJobResult(job);

// Custom polling options
Job job = client.waitForJob(jobId,
        WaitForJobOptions.builder()
                .interval(Duration.ofSeconds(3))
                .maxWait(Duration.ofMinutes(10))
                .build());