---
title: Send a document for signature from Java
description: Send a document for signature from Java, with a program that was run against Docustay before it was put here.
---

# Send a document for signature from Java

No install: this uses the HTTP client in Java 11 and newer.

Nothing to install: it uses java.net.http, added in Java 11, and runs as a single file with the java command. The Idempotency-Key header is made with UUID.randomUUID and you keep it if you retry. Build the JSON body with your usual library once it grows past a few fields.

```java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.UUID;

public class Send {
  public static void main(String[] args) throws Exception {
    String base = System.getenv().getOrDefault("DOCUSTAY_URL", "https://app.docustay.app");
    String body = "{\"templateId\":\"" + System.getenv("DOCUSTAY_TEMPLATE_ID") + "\","
      + "\"parties\":[{\"seat\":\"signer_1\",\"name\":\"Pat Example\",\"email\":\"pat@example.com\"}]}";
    HttpRequest request = HttpRequest.newBuilder(URI.create(base + "/api/v1/documents/send"))
      .header("Authorization", "Bearer " + System.getenv("DOCUSTAY_API_KEY"))
      .header("Content-Type", "application/json")
      .header("Idempotency-Key", UUID.randomUUID().toString())
      .POST(HttpRequest.BodyPublishers.ofString(body)).build();
    HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
    if (response.statusCode() >= 300) throw new RuntimeException("send failed (" + response.statusCode() + "): " + response.body());
    System.out.println(response.body());
  }
}
```

It reads DOCUSTAY_API_KEY and DOCUSTAY_TEMPLATE_ID from the environment. Use a test key first: it sends nothing real and bills nothing.

## Only the JDK

The Java program uses java.net.http, which has been part of the JDK since version 11, so there is no dependency to add and no build file to change. It builds a request with a Bearer header and a JSON body, sends it with an HttpClient and prints the status and the body. Read the key and the template id with System.getenv.

## Building the body

The example writes the JSON as a text block to stay free of libraries. In a real project use Jackson or Gson to build it from your own classes, and set the Idempotency-Key header to a UUID you keep with the record; a retry then reuses the key and gets the same document. Remember that the seat name in each party comes from the template.

## Handling failures

HttpClient does not throw for a 4xx or 5xx answer, so check statusCode yourself. A 401 means the key is wrong or lacks the permission, a 429 means slow down, and anything in the 5xx range is worth retrying with the same idempotency key. The body of an error always carries a request id that finds the call in the API log.

## Questions people ask

**Does a test key send real email?**

No. A test key emails only you, stamps the document TEST and is never counted against your plan.

**Which Java versions work?**

Java 11 and later, because the example uses the built-in HTTP client.

**Where do I see the result?**

In Documents in the app, and in the API log under Developers.

## Keep reading

- [Quick start](/docs/quickstart)
- [API reference](/docs/api-reference)
- [Webhooks](/docs/webhooks)
- [SDKs](/developers/sdks)
- [Test mode](/docs/test-mode)
- [Sending](/product/sending)
