How to Validate PDF/A Conformance with Java

Check whether a PDF conforms to a PDF/A profile using Java.
Share this page

By the end of this tutorial, you'll know how to validate PDF/A conformance with Java and the Query PDF API Tool. The sample asks Query PDF for the pdfa property and interprets the result without changing the source document. We'll explain the important request pieces so you can use the sample as the foundation for an integration that can validate PDF/A conformance.

Why Validate PDF/A Conformance with Java?

An archive intake service should verify a claimed archival file instead of trusting its filename or producer metadata. Query PDF can report whether the document satisfies a PDF/A standard before acceptance.

The adapted Java request sends pdfa in the queries field for /pdf-info. The result describes detected conformance; it does not convert a nonconforming file.

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 ValidatePDFA {

  // 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("queries", "pdfa")
            .build();
    Request request =
        new Request.Builder()
            .header("Api-Key", dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY))
            .url(API_URL + "/pdf-info")
            .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. The linked source provides the common request pattern; the code shown here applies it to Validate PDF/A Conformance.

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 supporting code 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 =

This setup 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("queries", "pdfa")
            .build();
    Request request =
        new Request.Builder()
            .header("Api-Key", dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY))
            .url(API_URL + "/pdf-info")
            .post(requestBody)
            .build();
    try {
      OkHttpClient client =
          new OkHttpClient().newBuilder().readTimeout(60, TimeUnit.SECONDS).build();

The adapted Java request sends pdfa in the queries field for /pdf-info. The result describes detected conformance; it does not convert a nonconforming file. The body construction 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 + "/pdf-info")
            .post(requestBody)
            .build();
    try {
      OkHttpClient client =
          new OkHttpClient().newBuilder().readTimeout(60, TimeUnit.SECONDS).build();

This builder chain 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 query result reports detected PDF/A conformance rather than creating a new file, allowing the application to accept, reject, or route the original PDF for conversion.

Beyond the Tutorial

By working through this example, you now have a Java pattern you can use to validate PDF/A conformance. With that foundation, you can use this check to route failures to PDF/A conversion, flag supplier issues, or enforce records-ingestion policy.

When this becomes part of an application, keep in mind that this query reports detected conformance; it does not repair or convert a failing document. Use the result to accept compliant files or route others to Convert PDF to PDF/A, and keep the required profile level in application policy rather than inferring it from a filename.

API Lab lets you try the Validate PDF/A Conformance operation without first building an application. When you are ready to implement it, see the Query PDF API Tool documentation for the complete API contract.

Note: The Validate PDF/A Conformance example above uses multipart form data; for callers that have already uploaded the source, follow the JSON payload example.

Generate a self-service API Key now!
Create your FREE API Key to start processing PDFs in seconds, only possible with pdfRest.