# Java SDK

Use the `io.cronitor:client` library to report job runs, heartbeats, and metrics to Cronitor from Java 8 or later.

## Install

Add the dependency to your Maven `pom.xml`:

```xml
<dependency>
    <groupId>io.cronitor</groupId>
    <artifactId>client</artifactId>
    <version>1.6.0</version>
</dependency>
```

With Gradle, add `implementation "io.cronitor:client:1.6.0"` to `dependencies`.

## Configure

Set the `CRONITOR_API_KEY` environment variable to your SDK Integration key. Copy the key from Settings → API Keys at https://cronitor.io/app/settings/api. Keep the key in the environment or a secret store of the runtime. Do not commit it.

The library does not read environment variables. Give the key to the client:

```java
import io.cronitor.client.CronitorClient;

CronitorClient cronitor = new CronitorClient(System.getenv("CRONITOR_API_KEY"));
```

To send events to an environment other than the default, give the environment as the second argument: `new CronitorClient(System.getenv("CRONITOR_API_KEY"), "staging")`.

## Monitor a job

The library has no job wrapper. Send the `run`, `complete`, and `fail` events around the work of the job:

```java
import io.cronitor.client.CronitorClient;

public class SendInvoices {
    public static void main(String[] args) throws Exception {
        CronitorClient cronitor = new CronitorClient(System.getenv("CRONITOR_API_KEY"));

        cronitor.run("send-invoices");
        try {
            sendInvoices();
            cronitor.complete("send-invoices");
        } catch (Exception e) {
            cronitor.fail("send-invoices", e.getMessage());
            throw e;
        }
    }
}
```

- Cronitor calculates the `duration` from the `run` event and the `complete` or `fail` event.
- The events go to the monitor with the key `send-invoices`. If no monitor has this key, Cronitor creates one on the first event.
- Each event method can throw `IOException`.

## Send a heartbeat

Send a tick each time the process completes a unit of useful work:

```java
cronitor.tick("queue-worker", "Alive!");
```

To attach metrics, give a `Map<String, Integer>`. The library sends each item as `metric=name:value`. It accepts integer values only:

```java
import java.util.HashMap;
import java.util.Map;

Map<String, Integer> metrics = new HashMap<>();
metrics.put("count", 100);
metrics.put("error_count", 3);
cronitor.tick("queue-worker", "Alive!", metrics);
```

`run`, `complete`, and `fail` accept the same message and metrics arguments.

If you only want to record custom metrics, use a heartbeat monitor. See [Custom Metrics](https://cronitor.io/docs/custom-metrics.md).

## Verify

After one real run, check the state of the monitor. A successful telemetry response shows only that Cronitor received the request. It does not show that Cronitor stored the event or matched it to a monitor.

With the [MCP server](https://cronitor.io/docs/mcp-server.md):

```text
get_status({"key": "send-invoices"})
```

With [CronitorCLI](https://cronitor.io/docs/using-cronitor-cli.md):

```bash
cronitor status send-invoices
```

## Reference

- [cronitor-java on GitHub](https://github.com/cronitorio/cronitor-java): the full README, including Spring configuration and pause.
- [Telemetry API](https://cronitor.io/docs/telemetry-api.md): the events and parameters that the library sends.
