Java SDK
BetaJDK 17+, zero dependencies, arbitrary precision via BigInteger.
Beta
Install
JDK 17+. JDK 17+, zero dependencies, arbitrary precision via BigInteger.
implementation("dev.counters:counters-sdk:0.1.0")Initialize
Build a client with your API key. CountersClient is AutoCloseable — use try-with-resources, or close() it yourself.
import dev.counters.sdk.CountersClient;
CountersClient client = CountersClient.builder()
.apiKey(System.getenv("COUNTERS_API_KEY"))
.build();Count
add and subtract are buffered and coalesced per counter (flushed as one POST /batch); addNow/subtractNow write immediately and return the counter. Each is overloaded for long, String, and BigInteger amounts.
var reg = client.counter("registrations");
reg.add(1); // buffered
reg.add(5); // coalesced
client.flush(); // one POST /batch
Counter c = reg.addNow(1); // immediate
System.out.println(c.value()); // "42"Read
Read the current value, or a per-bucket time series. Series parameters are passed as a SeriesParams record; from/to are OffsetDateTime.
ValueResponse v = reg.value();
var series = reg.series(new SeriesParams(
OffsetDateTime.parse("2026-01-01T00:00:00Z"),
OffsetDateTime.parse("2026-01-08T00:00:00Z"),
"1d"));Manage
clear resets to zero (new epoch, history retained); delete tombstones the counter; list pages the counters in the organization.
reg.clear();
reg.delete();
CounterPage page = client.list(null, 50); // cursor, limitLifecycle
Buffered writes flush on a daemon thread and at maxBatchSize. Close the client (or use try-with-resources) before exit so nothing is lost.
client.close(); // flush + stop the flusher threadErrors
Bad keys or amounts throw CountersValidationException before any request. Failed requests throw CountersApiException (status(), title()); both extend CountersException.
import dev.counters.sdk.CountersApiException;
import dev.counters.sdk.CountersValidationException;
try {
reg.addNow(1);
} catch (CountersValidationException e) {
throw e; // bad input
} catch (CountersApiException e) {
System.err.println(e.status() + " " + e.title());
}