How to Convert PDF to PDF/A with Java
This step-by-step tutorial explains how a Java application can convert PDF to PDF/A through the Convert to PDF/A API Tool. The sample selects a PDF/A conformance target with output_type and receives a newly converted PDF resource. After reviewing the example, you'll be ready to convert PDF to PDF/A with your own input.
Why Convert PDF to PDF/A with Java?
Records systems often require an archival profile before documents enter long-term retention. A Java workflow can create the PDF/A version consistently instead of depending on desktop conversion steps.
The request sends the source PDF to /pdfa and specifies the desired output_type. A successful conversion returns a new resource; applications should still validate that the selected profile matches their records policy.
Java Code Example
import io.github.cdimascio.dotenv.Dotenv;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import okhttp3.*;
import org.json.JSONObject;
public class PDFA {
// By default, we use the US-based API service. This is the primary endpoint for global use.
private static final String API_URL = "https://api.pdfrest.com";
// For GDPR compliance and enhanced performance for European users, you can switch to the EU-based
// service by commenting out the URL above and uncommenting the URL below.
// For more information visit https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work
// private static final String API_URL = "https://eu-api.pdfrest.com";
// Specify the path to your file here, or as the first argument when running the program.
private static final String DEFAULT_FILE_PATH = "/path/to/file.pdf";
// Specify your API key here, or in the environment variable PDFREST_API_KEY.
// You can also put the environment variable in a .env file.
private static final String DEFAULT_API_KEY = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
public static void main(String[] args) {
File inputFile;
if (args.length > 0) {
inputFile = new File(args[0]);
} else {
inputFile = new File(DEFAULT_FILE_PATH);
}
final Dotenv dotenv = Dotenv.configure().ignoreIfMalformed().ignoreIfMissing().load();
final RequestBody inputFileRequestBody =
RequestBody.create(inputFile, MediaType.parse("application/pdf"));
RequestBody requestBody =
new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", inputFile.getName(), inputFileRequestBody)
.addFormDataPart("output_type", "PDF/A-2u")
.addFormDataPart("output", "pdfrest_pdfa")
.build();
Request request =
new Request.Builder()
.header("Api-Key", dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY))
.url(API_URL + "/pdfa")
.post(requestBody)
.build();
try {
OkHttpClient client =
new OkHttpClient().newBuilder().readTimeout(60, TimeUnit.SECONDS).build();
Response response = client.newCall(request).execute();
System.out.println("Result code " + response.code());
if (response.body() != null) {
System.out.println(prettyJson(response.body().string()));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static String prettyJson(String json) {
// https://stackoverflow.com/a/9583835/11996393
return new JSONObject(json).toString(4);
}
}
Source: Java sample on GitHub.
Breaking Down the Code
Load the Java HTTP and JSON dependencies
import io.github.cdimascio.dotenv.Dotenv; import java.io.File; import java.io.IOException; import java.util.concurrent.TimeUnit; import okhttp3.*; import org.json.JSONObject;
The sample brings together the HTTP client, environment-based API key loading, and JSON utilities used later in the example.
Choose the input and load credentials
// service by commenting out the URL above and uncommenting the URL below.
// For more information visit https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work
// private static final String API_URL = "https://eu-api.pdfrest.com";
// Specify the path to your file here, or as the first argument when running the program.
private static final String DEFAULT_FILE_PATH = "/path/to/file.pdf";
// Specify your API key here, or in the environment variable PDFREST_API_KEY.
// You can also put the environment variable in a .env file.
private static final String DEFAULT_API_KEY = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
public static void main(String[] args) {
File inputFile;
if (args.length > 0) {
inputFile = new File(args[0]);
} else {
inputFile = new File(DEFAULT_FILE_PATH);
}
final Dotenv dotenv = Dotenv.configure().ignoreIfMalformed().ignoreIfMissing().load();
final RequestBody inputFileRequestBody =
The configuration block keeps a visible default path, accepts an override from the command line, and reads the API key through dotenv.
Build the multipart request body
final RequestBody inputFileRequestBody =
RequestBody.create(inputFile, MediaType.parse("application/pdf"));
RequestBody requestBody =
new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", inputFile.getName(), inputFileRequestBody)
.addFormDataPart("output_type", "PDF/A-2u")
.addFormDataPart("output", "pdfrest_pdfa")
.build();
Request request =
new Request.Builder()
.header("Api-Key", dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY))
.url(API_URL + "/pdfa")
.post(requestBody)
.build();
try {
OkHttpClient client =
The request sends the source PDF to /pdfa and specifies the desired output_type. A successful conversion returns a new resource; applications should still validate that the selected profile matches their records policy. The form-data setup packages fields and files together without hard-coding a Content-Type boundary.
Send the request to pdfRest
.build();
Request request =
new Request.Builder()
.header("Api-Key", dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY))
.url(API_URL + "/pdfa")
.post(requestBody)
.build();
try {
OkHttpClient client =
new OkHttpClient().newBuilder().readTimeout(60, TimeUnit.SECONDS).build();
The client request reads the credential through dotenv and targets the endpoint shown in the source, with the EU hostname documented beside the default US value.
Read the API response
OkHttpClient client =
new OkHttpClient().newBuilder().readTimeout(60, TimeUnit.SECONDS).build();
Response response = client.newCall(request).execute();
System.out.println("Result code " + response.code());
if (response.body() != null) {
System.out.println(prettyJson(response.body().string()));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static String prettyJson(String json) {
// https://stackoverflow.com/a/9583835/11996393
return new JSONObject(json).toString(4);
The response check checks the server result before treating the body as output and exposes diagnostic JSON when the operation cannot be completed.
Beyond the Tutorial
The completed example gives you a practical Java starting point for learning how to convert PDF to PDF/A. With that foundation, you can use PDF/A conversion for records packages, regulated archives, and document-management retention workflows.
As you apply the pattern to real documents, choose the conformance level from an actual records policy rather than selecting the newest profile by default. Validate the converted output as part of archival intake, and review documented error-handling options when source files contain features that cannot be represented directly.
Before integrating this workflow, test representative documents with the Convert PDF to PDF/A operation in API Lab. Then use the Convert to PDF/A API Tool documentation to review every available parameter and response field.
Note: The Convert PDF to PDF/A example above uses multipart form data; to reuse a resource ID, follow the JSON payload example.