Kestra Java SDK – Client Setup and Examples icon Kestra Java SDK – Client Setup and Examples

Interact with Kestra’s API via Java SDK.

Use the Kestra Java SDK

Installation

Choose the installation method that matches your environment.

For Maven users

Add this dependency to your project’s POM file:

<dependency>
<groupId>io.kestra</groupId>
<artifactId>kestra-api-client</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>

For Gradle users

Add this dependency to your build.gradle file:

implementation "io.kestra:kestra-api-client:1.0.0"

Manual installation

If you prefer to install the JAR manually, first generate it:

./gradlew publishToMavenLocal

Getting started

Initialize the KestraClient and reuse it across your application. Run this minimal example to verify your client setup:

import java.util.*;
import io.kestra.client.KestraClient; // Adjust import to your SDK package
public class GettingStarted {
// Instantiate the client once and reuse it (e.g., as a singleton)
private static final KestraClient CLIENT = KestraClient.builder()
.url("http://localhost:8080")
.basicAuth("root@root.com", "Root!1234") // or .tokenAuth("...") if you use tokens
.build();
public static void main(String[] args) {
// A lightweight example to confirm that the client was initialized
System.out.println("KestraClient initialized: " + (CLIENT != null));
}
}

Create a flow

Create a flow by sending the YAML definition as a string. This matches what you’d define in the UI, but through the SDK.

import java.util.*;
import io.kestra.client.KestraClient;
public class FlowsExamples {
private static final KestraClient CLIENT = KestraClient.builder()
.url("http://localhost:8080")
.basicAuth("root@root.com", "Root!1234")
.build();
public static void createFlow() {
String tenant = "main";
String flowBody = """
id: myflow
namespace: my.namespace
inputs:
- id: key
type: STRING
defaults: 'empty'
tasks:
- id: hello
type: io.kestra.plugin.core.log.Log
message: Hello World! 🚀
""";
CLIENT.flows().createFlow(tenant, flowBody);
System.out.println("Flow created: my.namespace/myflow");
}
}

Update a flow

Update by sending the full YAML for the flow (including the same id/namespace), then calling updateFlow.

import java.util.*;
import io.kestra.client.KestraClient;
public class FlowsUpdates {
private static final KestraClient CLIENT = KestraClient.builder()
.url("http://localhost:8080")
.basicAuth("root@root.com", "Root!1234")
.build();
public static void updateFlow() {
String flowId = "myflow";
String namespace = "my.namespace";
String tenant = "main";
String updatedFlowBody = """
id: myflow
namespace: my.namespace
inputs:
- id: key
type: STRING
defaults: 'empty'
tasks:
- id: hello
type: io.kestra.plugin.core.log.Log
message: Updated! 🚀
""";
CLIENT.flows().updateFlow(namespace, flowId, tenant, updatedFlowBody);
System.out.println("Flow updated: my.namespace/myflow");
}
}

Execute a flow

Trigger an execution and optionally pass inputs, labels, or scheduling parameters. You can choose to block (wait=true) until completion or return immediately.

import java.util.*;
import io.kestra.client.KestraClient;
import io.kestra.client.types.ExecutionKind; // Adjust to your SDK model package
public class ExecutionsExamples {
private static final KestraClient CLIENT = KestraClient.builder()
.url("http://localhost:8080")
.basicAuth("root@root.com", "Root!1234")
.build();
public static void createExecution() {
String flowId = "myflow";
String namespace = "my.namespace";
String tenant = "main";
Boolean wait = false; // non-blocking call
List<String> labels = List.of("label1:created");
Integer revision = null; // latest
String scheduleDate = null; // or ISO-8601 string, e.g. "2025-11-01T10:00:00Z"
List<String> breakpoints = List.of(); // task ids to pause at (for debugging)
ExecutionKind kind = ExecutionKind.NORMAL;
Map<String, Object> variables = Map.of(); // flow variables (if any)
Map<String, Object> inputs = new HashMap<>();
inputs.put("key", "value"); // matches the flow `inputs` definition
var exec = CLIENT.executions()
.createExecution(namespace, flowId, wait, tenant, labels, revision, scheduleDate, breakpoints, kind, variables, inputs);
System.out.println("Execution started: " + exec.getId());
}
}

Follow (stream) an execution

Stream execution events/logs as they happen. This is useful for building live console output or CI visibility.

import java.util.*;
import io.kestra.client.KestraClient;
public class ExecutionStreaming {
private static final KestraClient CLIENT = KestraClient.builder()
.url("http://localhost:8080")
.basicAuth("root@root.com", "Root!1234")
.build();
public static void followExecution() {
String executionId = "yourExecutionId";
String tenant = "main";
CLIENT.executions().followExecution(executionId, tenant)
.doOnNext(execution -> {
System.out.printf("Event: %s | Status: %s%n", execution.getId(), execution.getState());
})
.doOnError(err -> {
System.err.println("Stream error: " + err.getMessage());
})
.doOnComplete(() -> {
System.out.println("Execution stream completed.");
})
.subscribe();
}
}

Create one utility class to hold your client and reuse it everywhere:

import io.kestra.client.KestraClient;
public final class KestraClients {
private KestraClients() {}
public static final KestraClient INSTANCE = KestraClient.builder()
.url(System.getenv().getOrDefault("KESTRA_URL", "http://localhost:8080"))
// Choose one auth mechanism:
.basicAuth(
System.getenv().getOrDefault("KESTRA_USER", "root@root.com"),
System.getenv().getOrDefault("KESTRA_PASS", "Root!1234")
)
// .tokenAuth(System.getenv("KESTRA_TOKEN"))
.build();
}

Then, in your feature classes:

public class MyFlows {
public void create() {
KestraClients.INSTANCE.flows().createFlow("main", "...yaml...");
}
}

Was this page helpful?