Skip to the documentation
Java

Changelog

Every release of the package, newest first.

0.0.1

The first release of the Java SDK, sh.nextmail:nextmail. It needs Java 17 or later and has no dependency: requests go through java.net.http.HttpClient, and the JSON reader and writer are its own. It has a method for each of the 684 methods of the TypeScript SDK, in the same 53 namespaces and under the same names. They cover everything from sending and reading mail to contacts, broadcasts, automations, the calendar, booking pages, tasks and the settings of a workspace, and a parity check proves that each one sends the same request as its TypeScript twin.

  • new Nextmail() and Nextmail.builder() read NEXTMAIL_API_KEY, NEXTMAIL_ACCESS_TOKEN and NEXTMAIL_BASE_URL for anything left out, and the builder takes apiKey, accessToken, baseUrl, timeout, maxRetries, httpClient, userAgent and header. The client has an accessor for every namespace, such as emails(), threads() and domains(), and it is immutable and safe to share between threads.
  • A request body is a Map<String, Object> whose keys keep the camelCase names of the API, and Body.of builds one that keeps its order and takes null values. Options such as limit, cursor, idempotencyKey and the filters of a method go in an immutable RequestOptions, and a method refuses an option it does not take before anything is sent. A response comes back as the decoded Map<String, Object>.
  • Every paginated resource has list, which returns one Page, listAll, which returns every item as a List, and iterate, which returns a PagedIterable that fetches the next page only when the loop gets there.
  • An API refusal throws ApiException, or its subclass for the error type such as NotFoundException, ValidationException or RateLimitException, with status(), code(), param(), requestId() and checks such as isValidation() and isStepUpRequired(). No response at all throws NetworkException, with isTimeout() when the deadline passed. Every one is an unchecked NextmailException, and a mistake in the call itself throws IllegalArgumentException before anything is sent.
  • Reads, sends and every write that is safe to repeat are retried on 408, 500, 502, 503 and 504 with backoff, and on a 429 only when its Retry-After is a minute or less. Every send carries an idempotency key that its retries reuse, and the idempotencyKey option sets your own.
  • accessToken takes an OAuth access token, or a Supplier that returns one before every request, so the token can be renewed without a new client. When a change made with a token needs a verification code, the call throws with isStepUpRequired(), and security().beginStepUp and verifyStepUp provide one.
  • Nextmail.verifyWebhookSignature() checks a webhook delivery in constant time, refuses one more than five minutes old and returns the decoded event.
  • Nextmail.createTempMail() opens disposable inboxes with no credential, and client.raw().request() calls an endpoint no method wraps, with the credential, timeout and retries of the client.
  • Nextmail.toBase64(), isApiKey(), isAccessToken(), isSealed(), resolveLanguage(), languageByCode() and isRtlLanguage() are the helpers of the TypeScript SDK, and every set of values the API uses is a class in sh.nextmail.constants.
  • A credential goes over plain http: only to a server on this machine, the default HTTP client follows no redirects, and a credential never appears in toString(), in an exception or in its cause. When a newer version is out, the client says so once on standard error, only on a terminal, and NEXTMAIL_DISABLE_UPDATE_NOTICE=1 or disableUpdateNotice(true) turns that off.