# Quickstart

> For the complete documentation index, see [llms.txt](https://docs.lertha.com/llms.txt).
> Any documentation page is available as raw Markdown by appending `.md` to its URL.

> A task running on the orchestrator in ten minutes.

Prerequisites: JDK 25, the [`lertha` CLI](/cli), and a running orchestrator. For a laptop, the
fastest orchestrator is the throwaway one the CLI ships:

```bash
lertha dev
```

That gives you an orchestrator on `localhost:7233` and a UI on `localhost:8233`. In production the
address is the Lertha orchestrator's; see [Configuration](/develop/kotlin/configuration).

## 1. Define a task

```kotlin
data class GreetingInput(val greeting: String, val name: String)
data class Greeting(val text: String)

object GreetingTask : TaskHandler<GreetingInput, Greeting> {
    override val type = taskType<GreetingInput, Greeting>("ComposeGreeting")

    override suspend fun handle(input: GreetingInput, ctx: TaskContext): Greeting =
        Greeting("${input.greeting}, ${input.name}!")
}
```

No annotations, no engine imports. The type name is what the UI and the CLI show.

## 2. Run a worker

```kotlin
fun main() {
    EngineConnection.fromEnvironment().use { connection ->
        connection.runner("lab").use { runner ->
            runner.register(GreetingTask)
            runner.start()
            Thread.currentThread().join()
        }
    }
}
```

## 3. Start the task from application code

```kotlin
fun main(args: Array<String>) = runBlocking {
    EngineConnection.fromEnvironment().use { connection ->
        val orchestrator = connection.orchestrator()
        val options = RunOptions(
            id = "greeting-${UUID.randomUUID()}",
            queue = "lab",
            attemptTimeout = 10.seconds,
            retry = RetryPolicy(maxAttempts = 5, initialInterval = 500.milliseconds),
        )
        val greeting = orchestrator.run(GreetingTask.type, GreetingInput("Hello", "World"), options)
        println(greeting.text)
    }
}
```

`run` is `start` followed by `result()`. Use `start` when the caller should not wait.

## 4. Reach the same worker from the CLI

Because the handler registers under its plain type name:

```bash
lertha task run --type ComposeGreeting --id cli-1 --queue lab --timeout 10s \
  --input '{"greeting":"Hello","name":"CLI"}'
```

## Next

- Make it fail on purpose and watch the retries in the UI: [Tasks](/develop/kotlin/tasks).
- Put a loop and a human around it: [Flows](/develop/kotlin/flows).
- The lab repository `lerta-orchestration-lab` has all of this wired, with a `--fail N` flag.
