How to Poll for API Request Status with Java

Submit asynchronous pdfRest work and poll its status from Java.
Share this page

In this tutorial, we'll walk through how to poll for API request status with Java using the API Polling API Tool. The workflow requests asynchronous PDF/A processing, extracts the returned request ID, and checks its status through authenticated GET calls until completion or failure. You'll see how the request is assembled and how to work with the response returned when you poll for API request status.

Why Poll for API Request Status with Java?

Longer document operations can exceed the response window preferred by an application or gateway. Request polling lets the Java service receive a request ID immediately and check completion separately.

The initial POST uses the response-type: requestId header. Java then calls /request-status/{requestId} until the response is completed or reports a terminal failure.

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

  // 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 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";
  // 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";

  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();
    String apiKey = dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY);

    // Using PDF/A as an arbitrary example, send a request with a 'response-type' header.
    String pdfaResponse = getPdfaResponse(inputFile, apiKey);
    JSONObject pdfaJson = new JSONObject(pdfaResponse);
    if (pdfaJson.has("error")) {
      System.out.println("Error during PDFA call: " + pdfaJson.getString("error"));
    } else {
      // Get a request ID from the response.
      String requestID = pdfaJson.getString("requestId");

      // Check the request status.
      String requestStatusResponse = getRequestStatusResponse(requestID, apiKey);
      JSONObject requestStatusJson = new JSONObject(requestStatusResponse);

      // If still pending, check periodically for updates.
      while (requestStatusJson.getString("status").equals("pending")) {
        final int delay = 5000;
        try {
          Thread.sleep(delay);
          requestStatusResponse = getRequestStatusResponse(requestID, apiKey);
          requestStatusJson = new JSONObject(requestStatusResponse);
        } catch (InterruptedException e) {
          System.out.println(e);
        }
      }
    }
  }

  private static String getPdfaResponse(File inputFile, String apiKey) {

    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", apiKey)
            .header("response-type", "requestId")
            .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());
      String responseBody = response.body().string();
      System.out.println(prettyJson(responseBody));
      return responseBody;
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  private static String getRequestStatusResponse(String requestId, String apiKey) {
    String urlString = String.format(API_URL + "/request-status/%s", requestId);
    Request request = new Request.Builder().header("Api-Key", apiKey).url(urlString).get().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());
      String responseBody = response.body().string();
      System.out.println(prettyJson(responseBody));
      return responseBody;
    } 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 import block relies on OkHttp to send the call, dotenv to resolve credentials, and org.json to inspect or format JSON.

Choose the input and load credentials

// 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 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";
  // 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";

  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();
    String apiKey = dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY);

    // Using PDF/A as an arbitrary example, send a request with a 'response-type' header.

The constants section supports quick local testing while allowing normal callers to provide their own path and PDFREST_API_KEY.

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", apiKey)
            .header("response-type", "requestId")
            .url(API_URL + "/pdfa")
            .post(requestBody)
            .build();
    try {

The initial POST uses the response-type: requestId header. Java then calls /request-status/{requestId} until the response is completed or reports a terminal failure. This payload builder collects the named parts before OkHttp calculates the final multipart header and body encoding.

Send the request to pdfRest

Request request =
        new Request.Builder()
            .header("Api-Key", apiKey)
            .header("response-type", "requestId")
            .url(API_URL + "/pdfa")
            .post(requestBody)
            .build();
    try {
      OkHttpClient client =
          new OkHttpClient().newBuilder().readTimeout(60, TimeUnit.SECONDS).build();

The outbound call adds the API key header, selects the operation URL, and attaches the prepared body; changing the base constant switches between US and EU service hosts.

Read the request ID and wait for completion

JSONObject pdfaJson = new JSONObject(pdfaResponse);
    if (pdfaJson.has("error")) {
      System.out.println("Error during PDFA call: " + pdfaJson.getString("error"));
    } else {
      // Get a request ID from the response.
      String requestID = pdfaJson.getString("requestId");

      // Check the request status.
      String requestStatusResponse = getRequestStatusResponse(requestID, apiKey);
      JSONObject requestStatusJson = new JSONObject(requestStatusResponse);

      // If still pending, check periodically for updates.
      while (requestStatusJson.getString("status").equals("pending")) {
        final int delay = 5000;
        try {
          Thread.sleep(delay);
          requestStatusResponse = getRequestStatusResponse(requestID, apiKey);
          requestStatusJson = new JSONObject(requestStatusResponse);
        } catch (InterruptedException e) {
          System.out.println(e);
        }
      }
    }
  }

  private static String getPdfaResponse(File inputFile, String apiKey) {

The initial PDF/A response supplies requestId. The loop waits while the status remains pending, then asks the status endpoint again instead of resubmitting the document operation.

Build the status request

private static String getRequestStatusResponse(String requestId, String apiKey) {
    String urlString = String.format(API_URL + "/request-status/%s", requestId);
    Request request = new Request.Builder().header("Api-Key", apiKey).url(urlString).get().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());
      String responseBody = response.body().string();
      System.out.println(prettyJson(responseBody));
      return responseBody;
    } catch (IOException e) {

Status checks are authenticated GET requests whose URL includes the request ID; they do not send the original file or multipart body again.

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());
      String responseBody = response.body().string();
      System.out.println(prettyJson(responseBody));
      return responseBody;
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  private static String getRequestStatusResponse(String requestId, String apiKey) {
    String urlString = String.format(API_URL + "/request-status/%s", requestId);
    Request request = new Request.Builder().header("Api-Key", apiKey).url(urlString).get().build();

The response describes the asynchronous request state and returns its eventual result when processing is complete, so callers should also handle pending and terminal failure states.

Beyond the Tutorial

In this tutorial, we walked through how to poll for API request status with Java. With that foundation, you can use asynchronous polling for long-running conversions, large documents, and queue-based systems that should not hold one HTTP request open.

As you adapt this example for production, keep in mind that production polling should use a bounded interval, an overall timeout, and clear handling for completed and terminal failure states. Keep the request ID with the originating job so retries do not accidentally submit the expensive document operation again.

To continue exploring the Poll for API Request Status operation, visit API Lab. For complete request fields, defaults, and limitations, refer to the API Polling API Tool documentation.

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