> ## Documentation Index
> Fetch the complete documentation index at: https://docs-old.tilebox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Run your first workflow

> Define a small workflow task, start a direct runner, submit a job, and inspect the result.

This guide runs a minimal workflow with a direct runner. It gives you the fastest path to the Tilebox Workflows execution model before publishing workflow releases or deploying to a cluster.

Use this path when you are developing locally as a developer. If you want an agent to do the setup and iteration for you, start with [Onboard your agent](https://docs-old.tilebox.com/onboard-your-agent.md) and then follow [Iterate on workflow releases with agents](https://docs-old.tilebox.com/guides/workflows/agentic-workflow-iteration.md).

## Prerequisites

* You have a [Tilebox API key](https://docs-old.tilebox.com/authentication.md).
* You have installed the [Python SDK](https://docs-old.tilebox.com/sdks/python/install.md).

```bash theme={"system"}
uv add tilebox
export TILEBOX_API_KEY="YOUR_TILEBOX_API_KEY"
```

## Create a workflow file

Create a file named `hello_workflow.py`.

```python hello_workflow.py theme={"system"}
from tilebox.workflows import Client, ExecutionContext, Runner, Task


class HelloWorkflow(Task):
    name: str

    def execute(self, context: ExecutionContext) -> None:
        context.logger.info("Running root task", name=self.name)
        context.submit_subtask(WriteGreeting(name=self.name))


class WriteGreeting(Task):
    name: str

    def execute(self, context: ExecutionContext) -> None:
        context.logger.info("Hello from Tilebox", name=self.name)


if __name__ == "__main__":
    client = Client()
    runner = Runner(tasks=[HelloWorkflow, WriteGreeting])

    job = client.jobs().submit(
        "hello-workflow",
        HelloWorkflow(name="Earth"),
    )
    print(f"Submitted job: {job.id}")

    runner.connect_to(client).run_all()
```

The root task submits one subtask. Tilebox tracks both tasks as part of the same job, and the direct runner executes all eligible work.

## Run the workflow

Run the file locally.

```bash theme={"system"}
uv run python hello_workflow.py
```

The script submits a job, starts a direct runner, executes the root task and subtask, and exits after the queued work is complete.

## Inspect the job

Open the job in the [Tilebox Console](https://console.tilebox.com/workflows/jobs) to inspect task state, logs, and the execution trace.

For scripted inspection, use the jobs client or the Tilebox command-line tool:

```bash theme={"system"}
tilebox job logs <job-id>
tilebox job spans <job-id>
```

## Next steps

> [card] [Tasks](https://docs-old.tilebox.com/workflows/concepts/tasks.md)
>
> Define task inputs, subtasks, dependencies, retries, and identifiers.

> [card] [Build and deploy a workflow](https://docs-old.tilebox.com/guides/workflows/build-and-deploy-workflow.md)
>
> Package the same kind of workflow code as a release and deploy it to a cluster.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.