# Signals

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

> How the outside world reaches a running flow.

A **signal** is a message delivered to a running flow by name. It is how a human approval, a
webhook, or another service reaches a flow that is parked waiting for it.

Sending, from anywhere with a handle:

```kotlin
handle.signal("approval", Approval(approved = true, by = "abiola"))
```

Receiving, inside the flow body:

```kotlin
val approvals = flow.signals<Approval>("approval")
val approval = approvals.receive(30.minutes)   // null if nothing arrives in time
```

## Properties

- **Buffered from the start.** Signals that arrive before the body asks for them are kept, so a
  flow can ask late. `signals.available` says how many are waiting, usable inside `awaitUntil`.
- **Ordered** by arrival.
- **Durable.** The signal is recorded in the run's history. A worker that restarts replays it.
- **Closed runs refuse signals.** Sending to a finished run is an error, not a silent drop.

## The parked run

While a flow waits on `receive`, nothing is running anywhere: no poller, no cron, no row in a
table. The orchestrator holds the state and wakes the body when the signal lands, whether that is
in a second or in a week. That is the cheapest possible way to wait for a person.

**Remember:** a signal is data, not a command. The body decides what it means.
