Overview
Hurl captures let you extract values from HTTP responses and inject them into subsequent requests. This enables multi-step test flows — login to get a token, create a resource to get an ID, then verify and delete using those dynamic values.
How It Works
Basic Capture and Reuse
# Step 1: Login and capture token
POST http://localhost:3000/api/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "pass123"
}
HTTP 200
[Captures]
token: jsonpath "$.token"
user_id: jsonpath "$.user.id"
# Step 2: Use captured token
GET http://localhost:3000/api/users/{{user_id}}
Authorization: Bearer {{token}}
HTTP 200
[Asserts]
jsonpath "$.id" == {{user_id}}
jsonpath "$.email" == "user@example.com"Full CRUD Flow
# Login
POST {{base_url}}/api/auth/login
Content-Type: application/json
{ "email": "admin@test.com", "password": "admin123" }
HTTP 200
[Captures]
token: jsonpath "$.token"
# Create product
POST {{base_url}}/api/products
Authorization: Bearer {{token}}
Content-Type: application/json
{
"name": "Test Product",
"price": 29.99,
"category": "electronics"
}
HTTP 201
[Captures]
product_id: jsonpath "$.id"
[Asserts]
jsonpath "$.name" == "Test Product"
# Read product
GET {{base_url}}/api/products/{{product_id}}
Authorization: Bearer {{token}}
HTTP 200
[Asserts]
jsonpath "$.id" == {{product_id}}
jsonpath "$.name" == "Test Product"
jsonpath "$.price" == 29.99
# Update product
PATCH {{base_url}}/api/products/{{product_id}}
Authorization: Bearer {{token}}
Content-Type: application/json
{ "price": 39.99 }
HTTP 200
[Asserts]
jsonpath "$.price" == 39.99
# Delete product
DELETE {{base_url}}/api/products/{{product_id}}
Authorization: Bearer {{token}}
HTTP 204
# Verify deletion
GET {{base_url}}/api/products/{{product_id}}
Authorization: Bearer {{token}}
HTTP 404Capture Types
[Captures]
# JSONPath
token: jsonpath "$.data.token"
count: jsonpath "$.items" count
# Header
request_id: header "X-Request-Id"
etag: header "ETag"
# Body
raw_body: body
# Regex
version: regex "version: (\d+\.\d+)"
# Cookie
session: cookie "session_id"
Using External Variables
# Pass variables from CLI
hurl --test \
--variable base_url=http://localhost:3000 \
--variable admin_email=admin@test.com \
--variable admin_password=secret \
crud-flow.hurl
Best Practices
- -Capture dynamic values (IDs, tokens) immediately after creation
- -Use meaningful variable names:
product_id not id1 - -Pass environment-specific values via --variable (not hardcoded)
- -Clean up created resources at the end of test flows (DELETE step)
- -Chain captures forward — each step builds on previous captures
Common Mistakes
- -Hardcoding IDs instead of capturing from response
- -Not cleaning up test data (created resources persist between runs)
- -Variable name typos ({{tokken}} instead of {{token}})
- -Not asserting captured values in subsequent requests