Skip to main content
Hooks serve as a bridge between your backend or server-side scripts and the Autosana testing environment. They allow you to communicate data, set the state of the app, set the state of a user, etc. They are short programs that run in sandboxed environments during the testing process. They can be added to suites and flows, and any output from them (print statements, console.log, echo) is visible to the agent. A few common examples:
  1. Resetting a user’s onboarding in the backend via JS code
  2. Generating a random email to be used by the Autosana agent via Python code
  3. Returning a magic link or OTP code from your server for Autosana to use in the flow via a cURL request
  4. Mocking audio or video input by hitting an endpoint on your server via TypeScript code
Possibilities are endless and usually the more hooks the better, as it adds a level of determinism to the state of the test! Execution Positions There are three hook execution positions:
  1. Setup Hooks: Run before suites or flows start. Great for providing context.
  2. Runtime Hooks: Run as an action during the flow — added directly into flow instructions, allows real-time backend interaction during testing
  3. Teardown Hooks: Run at the very end of suites and flows. Helpful to clean up testing states

Hook Types

Hooks allow you to configure your test environment in three ways:
  1. Scripts: Python, JavaScript, TypeScript, or Bash scripts that run server-side
  2. cURL Requests: Backend API calls for simple HTTP requests
  3. App Launch Configuration: Configure how your mobile app launches (feature flags, environment settings) - mobile only

Scripts

Server-side scripts that execute in a secure sandbox environment. Choose from Python, JavaScript, TypeScript, or Bash depending on your needs.
If your hook calls a firewalled API, see Network allowlist for the IPs to allow.
Scripts run in a sandboxed environment and cannot use external libraries. Use only built-in/standard libraries (e.g., urllib instead of requests for Python, built-in fetch for JavaScript/TypeScript).
Because hook sandboxes are created from snapshots, pseudo-random generators can repeat values across runs. Avoid Math.random() in JavaScript/TypeScript and unseeded random in Python when generating emails, usernames, IDs, or other unique test data.
Common use cases:
  • Complex multi-step API operations
  • Data processing and transformation
  • Conditional logic based on API responses
  • Generating dynamic test data
  • Chaining multiple API calls with error handling

Generating Random Values

Use cryptographically secure randomness from the language standard library when generating unique test data. JavaScript / TypeScript:
Python:
If you must use Python’s random module, seed it from OS entropy at the top of your script:
If your flow types, taps or checks a printed value that changes every run, each run executes live. Export the value instead so cached runs can use it. See Hooks and Run Caching.

cURL Requests

Backend API calls that execute before (setup) or after (teardown) a flow runs. Best for simple, single HTTP requests. Common use cases:
  • Create test user accounts via your API
  • Reset database state between flows
  • Generate auth tokens or session data
  • Configure backend feature flags
  • Clean up test data after flows complete

App Launch Configuration (Mobile Only)

Configure values that are passed to your mobile app when it launches. These values are available to your app code as environment variables (iOS) or intent extras (Android).
App Launch Configuration is only available for mobile apps (iOS and Android). For web testing, use Scripts or cURL Requests to configure your test environment.
Common use cases:
  • Override feature flag values for specific test scenarios
  • Set test environment parameters (staging vs. production mode)
  • Configure API timeouts or retry behavior
  • Enable debug modes or verbose logging
  • Set experiment variants for A/B testing

Creating a Hook

  1. Navigate to Hooks in the sidebar
  2. Click Create Hook
  3. Enter a hook name (e.g., “Create Test User” or “Generate Auth Token”)
  4. Select hook type:
    • Python: For complex logic and data processing
    • JavaScript: For Node.js-based operations
    • TypeScript: For type-safe Node.js operations
    • Bash: For shell script operations
    • cURL Request: For simple HTTP API calls
    • App Launch Configuration: For mobile app settings (mobile only)
  5. Enter your script or configuration:

For Python:

For JavaScript:

For TypeScript:

For Bash:

For cURL Requests:

For App Launch Configuration:

  1. Click Create Hook
Any output from your hooks (print statements, console.log, echo) is passed to the agent as additional context. Use this to provide helpful information about what the hook did!

Testing Hooks

Before attaching hooks to flows, you can test them to verify they work correctly. Dashboard tests use your signed-in session. You do not need to create or paste an Autosana API key.
  1. Open the hook you want to test
  2. Click the Test Hook button
  3. The hook will execute with a 1-minute timeout
  4. View the output to verify success or debug issues
What to check:
  • Script executes without errors
  • API calls return expected responses
  • Environment variables are being read correctly
  • Exported values (if any) are formatted correctly
Always test hooks independently before attaching them to flows. This helps isolate issues and speeds up debugging.

Using Hooks

Setup & Teardown Hooks

Attaching Setup & Teardown Hooks
  1. Create a new suite or flow or click Edit on an existing one
  2. Expand the Advanced section
  3. Expand the Setup Hooks or Teardown Hooks section
  4. Click the Add a setup hook… or Add a teardown hook… button
  5. Select the hook you want to attach
Hooks attached to a suite are also shown read-only when you expand the suite on the Flows page, so you can see what runs before and after the suite without opening the editor.

Runtime Hooks

You can execute hooks as actions during flow execution by using the syntax ${hooks:Hook Name} in the flow instructions. Example:
When the agent encounters ${hooks:Hook Name}, it will:
  1. Look up the hook by name
  2. Execute the hook script
  3. Continue with the rest of the action
This is useful for:
  • Creating data mid-flow (e.g., “add 5 items to cart, then ${hooks:Create Dummy Discount Code}”)
  • Triggering backend events at specific points
  • Resetting state between actions
Runtime Hooks execute synchronously - the flow waits for the hook to complete before continuing.

Execution Order

  1. Setup Hooks execute (if configured)
  2. Flow runs on app start
  3. Agent runs actions and any Runtime Hooks (if configured)
  4. Flow run stops
  5. Teardown Hooks execute (if configured)
Steps 1 and 2 overlap when a setup hook is an App Launch Configuration — the app starts at that hook’s position.

Environment Variables in Hooks

For cURL Requests

Reference environment variables using ${env:VARIABLE_NAME} syntax:
Environment variables (in Settings → Environments):
  • API_URL = https://staging-api.example.com
  • TEST_EMAIL = test@staging.com
  • TEST_PASSWORD = SecurePass123
Executed command:

For Scripts (Python, JavaScript, TypeScript, Bash)

Environment variables are automatically injected into the script environment. Access them using your language’s standard method: Python:
JavaScript / TypeScript:
Bash:
Learn more about environment variables →
Click Insert Environment Variable when creating/editing a hook to browse and select from your available environment variables.

Run Metadata

Every hook in a run can read details about that run. This is useful for linking your own logs or error reports back to the Autosana run. Read them like any other environment variable, or use ${env:AUTOSANA_FLOW_RUN_ID} in cURL and App Launch Configuration hooks. They can’t be overwritten and aren’t set in Test Hook.

Example: Tagging Errors in Your App

Add an App Launch Configuration setup hook to the flow:
Read autosanaRunId when your app starts and add it as a tag in your error tracker, for example Sentry.setTag("autosana_run_id", autosanaRunId).

Sharing Data Between Hooks

Hooks can pass data to subsequent hooks in the same suite. This is useful for scenarios like:
  • Generating an auth token in a setup hook and using it in a runtime hook
  • Creating a test user and passing the user ID to a teardown hook for cleanup
  • Sharing credentials across multiple flows in a suite

How It Works

  1. In your hook, write values to /tmp/autosana.env in KEY=VALUE format
  2. Subsequent hooks can access these values as environment variables
  3. Values persist for all subsequent hooks in the suite (across all flows)

Key Naming Rules

When exporting values, keys must follow these rules:

Example: Passing a Token Between Hooks

Setup Hook (Python) - Creates token:
Runtime Hook (cURL) - Uses the token:
Teardown Hook (Python) - Cleans up:

Important Notes

  • Scripts can read and write exported values
  • cURL hooks can only read exported values (they cannot write to /tmp/autosana.env)
  • If multiple hooks export the same key, the latest value wins
  • Exported values are available to all subsequent hooks in the suite (across all flows)
  • Exported values are also available to subsequent flows in the suite via ${env:KEY}
  • The agent can also retrieve exported values directly by name using Get Variable
Hook exports are part of Autosana’s runtime variable system. For a complete overview of how variables work across hooks, flows, and suites, see Variables.

Hooks and Run Caching

Run Caching speeds up a flow by replaying what a previous passing run did, instead of working it out again. Whether that replay is possible depends on how your hook passes values to the flow. If your hook exports a new value every run — a phone number, a test account, a booking reference — Autosana has to learn that the value is meant to change. Until it does, those runs skip the cache. They still pass or fail correctly; they are just slower.

Export the Values Your Flow Uses

Do this. Write the value to /tmp/autosana.env under a name, so each run can be given its own:
Then reference it in your flow instructions as ${env:TEST_PHONE}, or have the agent fetch it with Get Variable. Not this. Printing it is the only record, and there is no name to look it up by:
What a setup hook prints is not part of the cache key. If a recorded run typed, tapped or checked a printed value, a later run replays only when your hook prints the same value; otherwise that run executes live and records again. The exception is a printed copy of an export Autosana already treats as changing (see the Tip below): replay fills in the new value instead. A printed value the flow never uses, such as an ID or timestamp, does not stop runs from replaying, though a short one that happens to match text in a step can occasionally send a run live. Values shorter than 4 characters are not checked, so a recording that used one can replay after it changes.
Use hook output to explain what the hook did. Printing an export’s value is fine once Autosana treats that export as changing under the rules below. A printed value your flow uses that is not covered by those rules — such as a short code (a 6-digit OTP) or a differently formatted copy — still makes each run with a new value execute live.

Which Values Autosana Treats as Changing

For web runs, exported BASE_URL and API_BASE_URL origins qualify automatically without a changing-value learning period. See preview-deployment caching for the required origin format and navigation limits. For other custom exports, Autosana compares each value against what the same hook exported last time — same flow version, same environment — and treats it as changing only if it actually changed. The built-in lease hooks automatically recognize AUTOSANA_EMAIL_ADDRESS, AUTOSANA_PHONE_NUMBER, and AUTOSANA_PHONE_NUMBER_NATIONAL, including both exported phone formats. See OTP testing for these hooks. For other custom exports, it takes three passing runs to settle: the first records the value, the second notices it changed and rebuilds the cache, the third can use it. Failed runs do not count. This is tracked per flow version and environment, so editing the flow’s instructions starts the count over.

When Only Some Steps Can Be Cached

A setup hook does not automatically turn caching off. For built-in leased identities and custom exports that meet the rules above, cached typing steps and descriptions can use the current run’s value. If a step contains a changed value that Autosana cannot replace reliably — for example, an encoded copy, a phone format other than either exported form, or the exact same value shared by two exports — the agent handles that step live. Earlier independent steps can still use the cache. Autosana resumes caching afterward only when it can confirm the required live action ran and the app matches a later checkpoint; otherwise the remaining steps run live. These partly cached runs still receive a fresh review. Other printed values work differently: if the recording used a printed value and this run’s hook prints a different one, the whole run executes live. A printed copy of an export that meets the rules above is the exception and is handled like the export.

Runtime Hooks and Caching

A cached run executes each runtime hook again at the same step, so its side effects happen on every run.
  • Exit with a non-zero code to fail a check. A cached run reads only the exit code, not the output. If the hook fails, the agent finishes the rest of the run live.
  • Values that change each run end the cached part. If a runtime hook returns a new value each run — such as a sign-in code or order number — and a later step types or taps it, the agent finishes the run live from that hook onward.

Flows That Are Never Cached

Using the Set Variable action turns caching off for a flow, whatever your hooks do.

Hook Examples

cURL Examples

Create User Account

Reset Database

Generate Auth Token

Delete Test Data (Teardown)

Script Examples

Python: Create User and Export Credentials

JavaScript: Fetch and Process Data

Bash: Quick API Check

App Launch Configuration (Mobile Only)

How It Works

App Launch Configuration hooks pass values to your mobile app when it launches. These values are set at app startup and are available throughout your test. This feature is only available for iOS and Android apps.

When It Runs

Setup hooks all run before the app starts — unless one of them is a launch configuration, in which case the app starts at that hook’s position. Put a hook that mints a token or seeds a user above it; hooks below it run against the already-running app. More than one. Each applies at its own position, restarting the app if it is already running. Nested objects merge — setting featureFlags.darkMode keeps the other featureFlags keys — while lists and single values are replaced. A restart keeps device data, not screen state. The app is not reinstalled or reset, so keychain, saved sessions and local databases survive, but the process restarts and the flow begins at your app’s launch screen. In a suite, flows share one session — opened by the suite’s own launch configuration if it declares one. A flow’s launch configuration restarts the app with its values merged over the suite’s; a flow with none keeps what the session already has. With Run flows in parallel, each flow gets its own session and applies the suite’s configuration from scratch.

Dynamic Values (Environment & Build Variables)

Launch configuration JSON supports ${env:VARIABLE_NAME} placeholders, resolved when the hook runs — so a placeholder sees values exported by setup hooks above it, as well as your environment variables and build variables passed via CI (the variables input on the GitHub Action / upload API). This lets you drive launch configuration dynamically — for example, passing an Expo Updates channel from CI:
The resolved value is delivered to your app as an iOS environment variable / Android intent extra (see below). Your app is responsible for acting on it — e.g. an Expo app must read the value and call Updates.setUpdateURLAndRequestHeadersOverride(...) followed by Updates.reloadAsync() to switch channels at runtime. If a referenced variable is not set — or is set to an empty or whitespace-only value — the run stops with an error naming it, rather than starting your app with a literal ${env:...} string.

Accessing Values in Your App

iOS (Swift):
Android (Kotlin):
React Native:
On iOS, launch configuration values are set as environment variables and accessed via ProcessInfo.processInfo.environment. On Android, they are passed as intent extras and accessed via intent.extras. See the platform-specific examples above for details.

Launch Configuration Examples

Override Feature Flags

Set Environment and Timeouts

A/B Testing Configuration

Debug Mode Settings

When to Use Each Hook Type

Setup Hooks & Agent Context

Pro Tip: When a hook produces output (via print statements, console.log, or echo), the agent automatically receives this data as additional context and can use it during flow execution. Example setup hook:
The agent receives this output and can reference it if needed during the flow execution.
Printing a value that changes every run — a timestamp, a fresh ID — does not affect the run cache unless your flow uses that value. See Hooks and Run Caching.

Timeouts

Hooks have different timeout limits depending on the context: If a hook exceeds its timeout, it will be terminated and marked as failed.
Keep hooks focused and fast. If you have long-running operations, consider breaking them into multiple hooks or optimizing your API calls.

Best Practices

Use Descriptive NamesName hooks after what they do: “Create Premium Test User” instead of “Hook 1”
Store Secrets in Environment VariablesNever hardcode API keys or passwords in hooks. Use environment variables like ${env:API_KEY}.
Test Hooks IndependentlyUse the Test button to verify your hooks work correctly before attaching them to flows.
Use Teardown Hooks for CleanupAlways clean up test data created by setup hooks to avoid polluting your backend. For concurrent runs, follow Making Suites, Parallelizable, Isolated, and Repeatable so one session cannot change or delete another session’s data.
Keep Hooks SimpleEach hook should do one thing. Create separate hooks for different setup tasks.
Use Scripts for Complex LogicWhen you need conditionals, loops, error handling, or data processing, use Python/JavaScript instead of complex cURL commands.
Export Only What You NeedWhen sharing data between hooks, only export the values that subsequent hooks actually need.
Add Helpful Print StatementsOutput from your hooks is passed to the agent. Add print statements to provide context about what happened.

Hooks vs Suite Auth Instructions

Use hooks when: You need to configure backend state, create test data, or call APIs Use suite auth instructions when: You need to start the suite from a specific state (e.g., logged in with a certain test account)

Troubleshooting

Script Issues

Script times out
  • Hooks have a 5-minute timeout during flow execution (1 minute when testing)
  • Break long operations into multiple hooks
  • Check for infinite loops or slow API endpoints
Environment variable not found
  • Verify the variable exists in Settings → Environments
  • Check spelling and case (variable names are case-sensitive)
  • For scripts, use the correct access method for your language
Random values are the same every run
  • Hook sandboxes are created from snapshots, so pseudo-random generators may repeat their seed across runs
  • In JavaScript/TypeScript, use Node’s built-in crypto module (crypto.randomInt, crypto.randomUUID) instead of Math.random()
  • In Python, prefer secrets or uuid; if you must use random, call random.seed(os.urandom(32)) before generating values
Exported values not available in next hook
  • Verify you wrote to /tmp/autosana.env (exact path)
  • Check key naming rules (alphanumeric + underscore, can’t start with number)
  • Ensure the format is KEY=VALUE with one per line

cURL Request Issues

Hook fails to execute
  • Verify the curl command works in your terminal first
  • Check that environment variables are defined
  • Ensure API endpoints are accessible from Autosana’s infrastructure
Environment variables not replacing
  • Syntax must be ${env:VARIABLE_NAME} (not {{VARIABLE_NAME}} or $VARIABLE_NAME)
  • Variable names are case-sensitive
  • Variables must exist in Settings → Environments

App Launch Configuration Issues

Configuration not appearing in app
  • Verify JSON is valid (use a JSON validator)
  • Check you’re accessing values correctly for your platform (ProcessInfo for iOS, intent.extras for Android)
  • Ensure the hook is attached as a setup hook (launch configuration doesn’t work in teardown)
Values have wrong type
  • On iOS, all values become strings (including numbers and booleans)
  • On Android, primitives keep their types (int, float, boolean, string)
  • Nested objects are JSON-serialized as strings on both platforms
  • Use the examples in this guide to parse nested structures correctly

Data Sharing Issues

Hook can’t read value from previous hook
  • Ensure the previous hook successfully wrote to /tmp/autosana.env
  • Check that the previous hook completed without errors
  • Verify the key name matches exactly (case-sensitive)
Invalid key name warning
  • Keys must contain only letters, numbers, and underscores
  • Keys cannot start with a number
  • Examples: AUTH_TOKEN ✓, 123_KEY ✗, API-KEY ✗

Managing Hooks via API

Hooks can be created, updated, and deleted programmatically via the Hooks API. Useful for syncing hook definitions from your repo, bulk-importing from another system, or wiring up custom tooling. Hooks can also live as script files in your repository and be referenced from code-managed flows — see Hooks as files.

Next Steps