---
sidebar_position: 4
title: Collection and Request Lifecycle
description: Understand what Hen prepares before execution and what happens when each request runs.
---
This page explains the two levels of Hen execution:
1. how a collection is prepared
2. what happens when a request runs
## Collection lifecycle
Everything before the first `---` is the **preamble**.
That is where you declare global collection values such as:
- scalar variables
- prompt placeholders
- secret-backed values
- arrays
- named environments
- collection-wide defaults such as reliability settings
```hen
name = Example Collection
$ API_ORIGIN = https://api.example.com
$ API_KEY = secret.env("HEN_API_KEY")
$ USER_ID = [[ user_id ]]
env local
$ API_ORIGIN = http://localhost:3000
```
Before a run starts, Hen prepares the collection by resolving those inputs in order:
1. collection-level scalar assignments
2. selected environment overrides
3. explicit CLI `--input key=value` values
4. prompt defaults
5. runtime captures and callback exports from earlier requests
After the preamble, each `---` starts a request block.
## Request lifecycle
A request block usually contains:
1. a request title
2. a target line such as `GET https://example.com`
3. request-local directives, headers, query params, forms, and body
4. assertions
5. captures
6. optional callbacks
```hen
Get user
GET {{ API_ORIGIN }}/users/{{ USER_ID }}
* Authorization = Bearer {{ API_KEY }}
^ & status == 200
& body.id -> $FETCHED_USER_ID
! ./scripts/notify.sh
```
## What `&` means
After a request runs, Hen exposes the response through the `&` accessor space.
That response can be used in:
- assertions
- captures
- dependency captures
Examples:
```hen
^ & status == 200
^ & body.user.name == "alice"
& body.user.id -> $USER_ID
& header.content_type -> $CONTENT_TYPE
```
The most common response roots are:
- `& status`
- `& body`
- `& header`
So when you write:
```hen
^ & status == 200
```
you are asserting against the response from the request that just executed.
## Order of operations for one request
At a high level, Hen handles a request in this order:
1. resolve variables, prompts, and any dependency values needed by the request
2. build the request target, headers, query params, forms, and body
3. execute the request
4. expose the response through `& ...`
5. evaluate assertions against that response
6. apply captures to export values for later requests
7. run callbacks
Callbacks run **after** request execution, which makes them a good fit for notifications,
post-processing, or local side effects.
## Dependencies extend the lifecycle across requests
When one request depends on another, the earlier request must complete first:
```hen
Create user
POST {{ API_ORIGIN }}/users
~~~json
{"name":"alice"}
~~~
^ & status == 201
& body.id -> $USER_ID
---
Load user
> requires: Create user
GET {{ API_ORIGIN }}/users/{{ USER_ID }}
^ & status == 200
```
In that flow:
1. `Create user` runs first
2. its response is exposed through `& ...`
3. its capture exports `$USER_ID`
4. `Load user` can then use that captured value
## `verify` vs `run`
- `hen verify` checks the collection structure without executing requests or callbacks
- `hen run` executes requests, exposes responses through `& ...`, applies captures, and runs callbacks
## Read next
- [Syntax Cheatsheet](./syntax-cheatsheet.md)
- [Interactive CLI](./interactive-cli.md)
- [Captures and Assertions](../reference/captures-and-assertions.md)
- [Dependencies, Fragments, and Callbacks](../reference/dependencies-fragments-callbacks.md)