Top-level fields
| Field |
Required |
Type |
Description |
version | No | string | Schema version ("1" only) |
name | No* | string | Top-level test suite name (*recommended) |
description | No | string | Suite description |
tags | No | [string] | Tags for filtering with --tag |
env | No | object | Inline environment variables |
cookies | No | string | "auto" (default), "off", "per-test" |
redaction | No | object | Report-time redaction of headers, env, captures |
defaults | No | object | Project-wide request defaults (headers, auth, timeout) |
setup | No | [step] | Setup steps run before all tests |
teardown | No | [step] | Teardown steps run after all tests |
tests | See note | [test] | Named test groups (mutually exclusive with steps) |
steps | See note | [step] | Flat (unnamed) steps (mutually exclusive with tests) |
At least one of steps or tests must be present.
Step fields
| Field |
Required |
Type |
Description |
name | Yes | string | Step name (display and identification) |
request | Yes | object | HTTP request (method + url required) |
capture | No | object | Capture variables from response |
assert | No | object | Response assertions |
poll | No | object | Polling configuration (until, interval, max_attempts) |
retries | No | integer | Retry count for transient failures |
timeout | No | integer | Per-step timeout in milliseconds |
connect_timeout | No | integer | TCP connection timeout in milliseconds |
delay | No | integer | Delay before step in milliseconds |
follow_redirects | No | boolean | Whether to follow redirects (default: true) |
max_redirs | No | integer | Maximum redirects to follow |
cookies | No | string/boolean | "off" to disable, string for named jar, true/false |
script | No | string | Inline Lua script (optional feature) |
if | No | string | Skip step unless interpolated expression is truthy |
unless | No | string | Skip step if interpolated expression is truthy |
debug | No | boolean | Record full response for debugging |
Request fields
| Field |
Required |
Type |
Description |
method | Yes | string | HTTP method (GET, POST, PUT, PATCH, DELETE, etc.) |
url | Yes | string | Request URL with {{ ... }} interpolation |
headers | No | object | HTTP headers (key: value) |
body | No | any | JSON body (object/array), or plain text (string) |
form | No | object | Form-urlencoded body |
graphql | No | object | GraphQL query (query, variables, operation_name) |
multipart | No | object | Multipart form data (fields + files) |
auth | No | object | Auth config (bearer token or basic credentials) |
Assert fields
| Field |
Type |
Description |
status | integer / string / object | Status assertion (exact, shorthand, or complex) |
body | object | Body assertions keyed by JSONPath |
headers | object | Response header assertions |
duration | string | Duration assertion ("< 500ms", etc.) |
redirect | object | Redirect assertions (url, count) |
Capture fields
| Key |
Value / Sub-fields |
Description |
name: "$.json.path" | string (JSONPath) | Capture from body JSONPath (shorthand) |
name.jsonpath | string | Explicit JSONPath capture from body |
name.header | string | Capture from response header |
name.cookie | string | Capture cookie by name from Set-Cookie |
name.body | true | Capture whole response body as string |
name.status | true | Capture HTTP status code as number |
name.url | true | Capture final URL after redirects |
name.regex | string | Regex capture group 1 (on header/body sources) |
name.optional | true | Don't fail if source is missing |
name.default | any | Fallback value when source yields no match |
name.when | object | Status gate ({ status: 201 } or { status: "2xx" }) |
Poll configuration
| Field |
Required |
Type |
Description |
until | Yes | object | Assertions that must pass to stop polling |
interval | Yes | string/ms | Polling interval (e.g. "1s", 500) |
max_attempts | Yes | integer | Maximum polling attempts before failure |
Include directive
| Field |
Required |
Type |
Description |
include | Yes | string | Path to shared .tarn.yaml file |
with | No | object | Parameters to pass ({{ params.x }}) |
override | No | object | Override env/cookies/defaults from included file |
Auth config
| Field |
Type |
Example |
auth.bearer | string | auth: { bearer: "{{ capture.token }}" } |
auth.basic | object | auth: { basic: { username: "admin", password: "pass" } } |