Authorize your Domains

Once you have your account set up, you need to associate your domains with it. This is done by creating an Authorization object:

Registration registration = ... // your Registration object

Authorization auth = registration.authorizeDomain("");

The Authorization instance contains further details about how you can prove ownership of your domain. An ACME server offers combinations of different authorization methods, called Challenges.

Authorization methods help you find the Challenge that fits best to your possibilities. Just pass all the challenge types that your software is able to accept to findCombination(), and it returns the shortest possible combination of Challenges you have to perform.

In the following example, your software would be able to either perform a HTTP or DNS challenge, or both:

Collection<Challenge> combination = auth.findCombination(
        Http01Challenge.TYPE, Dns01Challenge.TYPE);

The returned combination contains a single combination of challenges you would have to perform. If the combination consists of more than one challenge, you will have to perform all of them in order to successfully authorize your domain. If the returned collection is empty, it means that none of your offered challenge types are acceptable to the CA.

If your software only supports a single challenge type, findChallenge() may be a little easier to use:

Http01Challenge challenge = auth.findChallenge(Http01Challenge.TYPE);

It returns a properly casted Challenge object, or null if your challenge type was not acceptable.

The Challenge object provides the necessary data for a successful verification of your domain ownership. The kind of response depends on the challenge type (see the documentation of challenges).

After you have performed the necessary steps to set up the response to the challenge (e.g. creating a file or modifying your DNS records), the ACME server is told to test your response:


Now you have to wait for the server to test your response and set the challenge status to VALID. The easiest way is to poll the status:

while (challenge.getStatus() != Status.VALID) {

This is a very simple example. You should limit the number of loop iterations, and abort the loop when the status should turn to INVALID. If you know when the CA server actually requested your response (e.g. when you notice a HTTP request on the response file), you should start polling after that event.

update() may throw an AcmeRetryAfterException, giving an estimated time in getRetryAfter() for when the challenge is completed. You should then wait until that moment has been reached, before trying again. The challenge state is still updated when this exception is thrown.

As soon as all the necessary challenges are VALID, you have successfully associated the domain with your account.

If your final certificate will contain further domains or subdomains, repeat the authorization run with each of them.

Update an Authorization

The server also provides an authorization URL. It can be retrieved from Authorization.getLocation(). You can recreate the Authorization object at a later time just by binding it to your Session:

URL authUrl = ... // Authorization URL

Authorization auth = Authorization.bind(session, authUrl);

As soon as you invoke a getter, the Authorization object lazily loads the current server state of your authorization, including the domain name, the overall status, and an expiry date.

You can always invoke update() to read the current server state again. It may throw an AcmeRetryAfterException, giving an estimated time in getRetryAfter() for when all challenges are completed. The authorization state is still updated even when this exception is thrown. If you invoke update() for polling the authorization state, you should wait until the moment given in the exception has been reached before trying again.

Deactivate an Authorization

It is possible to deactivate an Authorization, for example if you sell the associated domain.


Restore a Challenge

Validating a challenge can take a considerable amount of time and is a candidate for asynchronous execution. This can be a problem if you need to keep the Challenge object for a later time or a different Java environment.

To recreate a Challenge object at a later time, all you need is to store the original object’s location property:

Challenge originalChallenge = ... // some Challenge instance
URL challengeUrl = originalChallenge.getLocation();

Later, you restore the Challenge object by invoking Challenge.bind().

URL challengeUrl = ... // challenge URL
Challenge restoredChallenge = Challenge.bind(session, challengeUrl);

The restoredChallenge already reflects the current state of the challenge.