Java SDK

Beta

JDK 17+, zero dependencies, arbitrary precision via BigInteger.

Install

JDK 17+. JDK 17+, zero dependencies, arbitrary precision via BigInteger.

Maven Central
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.

Main.java
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.

count
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.

read
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.

manage
reg.clear();
reg.delete();

CounterPage page = client.list(null, 50); // cursor, limit

Lifecycle

Buffered writes flush on a daemon thread and at maxBatchSize. Close the client (or use try-with-resources) before exit so nothing is lost.

lifecycle
client.close(); // flush + stop the flusher thread

Errors

Bad keys or amounts throw CountersValidationException before any request. Failed requests throw CountersApiException (status(), title()); both extend CountersException.

errors
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());
}
Prefer raw HTTP? See the REST API reference. Create a key in your dashboard.