# First workflow

Create a typed greeting workflow, verify its bytecode locally, start it and read its recorded outcome.

Create a small AWL project and run it against a local server. The greeting template is included in the public 0.31.0 crate. It takes a name and a choice of tone. It completes without a worker or an assistant.

## Before you begin

[Install Aion](/aion/getting-started/install/) and have one server running with deployment enabled. These examples use the default gRPC endpoint and namespace. For another server, pass the same endpoint and namespace to every remote command.

## Create the project

**Terminal**

```bash
aion new greet_visitor
cd greet_visitor
aion awl check greet_visitor.awl
```


The command creates the workflow, a development config and a README. The project name uses lowercase letters, digits and underscores, starting with a letter.

This is the generated workflow:

**greet_visitor.awl**

```text
//! Build a greeting, then choose its tone.
workflow greet_visitor
  input name: String
  input enthusiastic: Bool
  outcome greeted: type Greeting, route success

type Greeting { message: String }

step compose
  "Hello, " + name -> greeting

step punctuate after compose
  greeting + "!" -> excited_greeting

step finish after punctuate
  outcome excited: if enthusiastic,
    route greeted(message: excited_greeting)
  outcome calm: else,
    route greeted(message: greeting + ".")
```


Each step binds a value. The final step chooses one outcome arm. Both arms supply the record declared by the successful outcome.

## Check and compile locally

**Terminal**

```bash
aion awl check greet_visitor.awl
aion awl emit greet_visitor.awl --target beam --output greet_visitor.beam
aion awl schema greet_visitor.awl
```


The check reports three steps. The bytecode command writes a BEAM file and its JSON sidecar. Schema prints the input contract. These are local authoring operations.

The bytecode command checks that each construct can compile. A refusal names the construct and source location.

## Deploy, start and wait

**Terminal**

```bash
aion run greet_visitor.awl --input '{"name":"Ada","enthusiastic":true}'
```


The command compiles the document, checks the input, deploys the archive, starts a run and waits for a terminal event. Its JSON result includes both ids and this result envelope:

**Result payload inside the outcome**

```json
{"outcome":"greeted","payload":{"message":"Hello, Ada!"}}
```


A client wait bound is available in the [run command](/aion/reference/cli-authoring/#command-run). Reaching that bound stops the client waiting. The run continues on the server.

## Start without waiting

**Terminal**

```bash
aion deploy greet_visitor.awl
aion start greet_visitor --input '{"name":"Ada","enthusiastic":false}'
```


Copy the returned workflow id and run id into shell variables named in the next example. The calm branch records a greeting ending with a full stop.

**Terminal — copy both ids from the start receipt**

```bash
aion describe "$WORKFLOW_ID" --run-id "$RUN_ID" --pretty
aion inspect "$WORKFLOW_ID" --run-id "$RUN_ID" --pretty
aion tail "$WORKFLOW_ID" --run-id "$RUN_ID"
```


Describe reports status and run identity. Inspect reads the event history. Tail follows a live transcript, or replays a finished run and exits.

## If the run is refused

A disabled deploy surface, missing deploy grant or invalid input produces a refusal naming the required correction.

If the command cannot connect, read server status and the log. Do not restart a server to clear an unexplained failure.

## Continue

Learn [durability and replay](/aion/concepts/durability-and-replay/), then add [waits and signals](/aion/reference/awl-waits/) or [worker activities](/aion/concepts/workers-and-sdks/).
