Post-Request Hooks
A post-request hook is a lightweight script written in Rhai that Rumour runs immediately after receiving the HTTP response — but before assertions are checked, variables are extracted, or execution moves to the next step. It lets you inspect response metadata and payload content to perform complex validations or inject downstream variables dynamically.
Common Use Cases
- Downstream Variable Injection: Parsing tokens or values from responses and formatting them for upcoming API calls.
- Response Customization & Audits: Validating payload structure or inspecting headers programmatically.
- Logging & Observability: Printing response statistics or fields to the terminal for debugging purposes.
- Custom Control Flow: Halting the test workflow programmatically using
throwif critical business logic invariants are violated.
How It Works
To associate a post-request hook with your HTTP request, configure the post_request key inside your .toml request file. Rumour supports two placements for this key:
Option A: At the Root Level
You can define post_request directly at the root of the file:
name = "get_user_profile"
post_request = "my_script.rhai"
[request]
method = "GET"
url = "{{base_url}}/users/1"
Option B: Within the [request] Block
Alternatively, you can place it inside the [request] table alongside request properties like method and url:
name = "get_user_profile"
[request]
method = "GET"
url = "{{base_url}}/users/1"
post_request = "my_script.rhai"
Rumour checks for the hook at the root level first. If not defined there, it falls back to checking inside the [request] block.
File Location & Path Resolution
Rumour resolves the script path relative to the directory containing the request TOML file. This means you can keep scripts in sub-folders or parent folders by using relative paths:
- In the same folder:
post_request = "my_script.rhai" - In a sub-folder:
post_request = "scripts/my_script.rhai" - In a parent/sibling folder:
post_request = "../shared/logger.rhai"
This allows you to organize and reuse scripts across multiple requests in your collection:
scripting_examples/
├── shared/
│ └── logger.rhai
└── users/
├── workspace.env.toml
└── get_user.toml # Configured with: post_request = "../shared/logger.rhai"
Available Variables in the Script
When your post-request script runs, Rumour exposes the following objects to the script scope:
| Object | Type | Access | Description |
|---|---|---|---|
vars | Map | Read/Write | All runtime variables — modifications persist for downstream requests |
status | Integer | Read-Only | HTTP response status code (e.g. 200, 201, 404) |
res_headers | Map | Read-Only | Key/value map of all headers received in the response |
res_body | String | Read-Only | The raw response body payload |
Unlike the pre-request hook, you cannot modify res_headers or res_body here — these are the actual server response and are already captured. Only the vars object is writable.
Logging
You can call log("message") from any script to print a labeled message to the terminal during the run:
[SCRIPT] your message here
Example 1: Basic Response Verification & Extraction
Goal
After fetching a user, inspect the HTTP status code and store a flag variable (user_fetched) for downstream request steps to consume.
File Layout
scripting_examples/post_request/
├── workspace.env.toml
├── get_user.toml
└── check_status.rhai
File Contents
workspace.env.toml
# workspace.env.toml
base_url = "http://localhost:4000/api/v2"
get_user.toml
# get_user.toml
name = "post_hook_get_user"
[request]
method = "GET"
url = "{{base_url}}/users/1"
post_request = "check_status.rhai"
[assert]
status = 200
check_status.rhai
// check_status.rhai
log("Post-request: checking response status");
if status == 200 {
log("Response OK - storing custom derived variable");
vars["user_fetched"] = "true";
} else {
log("Unexpected status: " + status.to_string());
vars["user_fetched"] = "false";
}
Running the Example
Execute the request in verbose mode:
rumour run ./scripting_examples/post_request/get_user.toml -tv
Output Trace
GET http://localhost:4000/api/v2/users/1
URL: http://localhost:4000/api/v2/users/1
[SCRIPT] Post-request: checking response status
[SCRIPT] Response OK - storing custom derived variable
✓ SUCCESS: /home/bugsfounder/workspace/testing/scripting_examples/post_request/get_user.toml (2ms)
✓ ./scripting_examples/post_request/get_user.toml → PASS (1 Pass, 0 Fail, 0 Skip)
╭──────────────────────────────────────────────────────────────────────────╮
│ RUMOUR EXECUTION REPORT │
├──────────────────────────────────────────────────────────────────────────┤
│ Total Requests: 1 │
│ Successful: 1 │
│ Failed: 0 │
│ Skipped: 0 │
│ Success Rate: 100.0% │
│ Total Time: 6ms │
╰──────────────────────────────────────────────────────────────────────────╯
✓ Successful Requests:
- /home/bugsfounder/workspace/testing/scripting_examples/post_request/get_user.toml [200] [6ms]
Understanding the Output
The [SCRIPT] log lines show that the post-request script executed after the server responded. Because the status code was 200, the script set the variable user_fetched to "true". Subsequent requests in this workflow can now access this value using {{user_fetched}}.
Example 2: Advanced Response Inspection & Dynamic Extraction
Goal
Assert the response status programmatically, inspect response header keys, scan the raw response body for content, and inject downstream variables dynamically.
File Layout
scripting_examples/post_request/
├── workspace.env.toml
├── advanced_validation.toml
└── advanced_validation.rhai
File Contents
advanced_validation.toml
# advanced_validation.toml
name = "post_hook_advanced_validation"
[request]
method = "GET"
url = "{{base_url}}/users"
post_request = "advanced_validation.rhai"
[assert]
status = 200
advanced_validation.rhai
// advanced_validation.rhai
log("Advanced Post-request hook execution started.");
// 1. Assert status code programmatically
if status != 200 {
throw "Request failed with status code: " + status.to_string();
}
// 2. Inspect response headers (keys are normalized to lowercase)
let contentType = res_headers["content-type"];
log("Response Content-Type: " + contentType);
// 3. Inspect body content
if res_body.contains("dev_lead") {
log("Verified: Target user dev_lead found in response body.");
vars["extracted_username"] = "dev_lead";
vars["extracted_role"] = "lead";
} else {
log("Target user dev_lead not found in response.");
vars["extracted_username"] = "unknown";
}
log("Derived downstream variables: extracted_username=" + vars["extracted_username"]);
Running the Example
Execute the request in verbose mode:
rumour run ./scripting_examples/post_request/advanced_validation.toml -tv
Output Trace
GET http://localhost:4000/api/v2/users
URL: http://localhost:4000/api/v2/users
[SCRIPT] Advanced Post-request hook execution started.
[SCRIPT] Response Content-Type: application/json; charset=utf-8
[SCRIPT] Verified: Target user dev_lead found in response body.
[SCRIPT] Derived downstream variables: extracted_username=dev_lead
✓ SUCCESS: /home/bugsfounder/workspace/testing/scripting_examples/post_request/advanced_validation.toml (2ms)
✓ ./scripting_examples/post_request/advanced_validation.toml → PASS (1 Pass, 0 Fail, 0 Skip)
╭──────────────────────────────────────────────────────────────────────────╮
│ RUMOUR EXECUTION REPORT │
├──────────────────────────────────────────────────────────────────────────┤
│ Total Requests: 1 │
│ Successful: 1 │
│ Failed: 0 │
│ Skipped: 0 │
│ Success Rate: 100.0% │
│ Total Time: 9ms │
╰──────────────────────────────────────────────────────────────────────────╯
✓ Successful Requests:
- /home/bugsfounder/workspace/testing/scripting_examples/post_request/advanced_validation.toml [200] [9ms]
Understanding the Output
- The script started immediately after receiving response data.
- It extracted
res_headers["content-type"](which resolved toapplication/json; charset=utf-8). - It scanned the payload
res_bodyfor the substring"dev_lead". Finding it, the script successfully storedextracted_username = "dev_lead"andextracted_role = "lead"invarsfor use in subsequent requests.
Script Errors
If your script contains a syntax error or a runtime exception, Rumour halts execution of that request, marks the request result as failed, and skips any downstream dependent requests. The failure reason is printed in the execution report:
Reason: Script error: Script error in /absolute/path/to/check_status.rhai: Variable not found: typo_var (line 5, position 1)
Understanding the Error Output
When a script error occurs:
- Request Marked as Failed: Rumour halts and marks the request status as failed, even if the HTTP status code matched assertions.
- Error Details: It pinpoints the absolute path of the script, the exact error message (
Variable not found: typo_var), and the precise line/column number (line 5, position 1) where the problem occurred to help you debug quickly.