Best Practices & Examples

Real-world flow examples and strategies for building effective, maintainable flows.

Example: Authentication Flow

A 3-step flow that logs in, fetches the user profile, and updates it. Demonstrates token extraction and reuse across steps.

POSTStep 1: Login

URL: {{base_url}}/api/auth/login

Body:

{"email": "{{email}}", "password": "{{password}}"}

Extractions (post-response script):

NameSourceExpression
tokenJSON Pathdata.accessToken
refreshTokenJSON Pathdata.refreshToken
userIdJSON Pathdata.user.id
GETStep 2: Get Profile

URL: {{base_url}}/api/users/{{flow.userId}}

Headers:

Authorization: Bearer {{flow.token}}

Assertions (Processors tab):

✓ Status code equals 200

✓ Body JSON data.id equals {{flow.userId}}

Extractions:

NameSourceExpression
usernameJSON Pathdata.username
PUTStep 3: Update Profile

URL: {{base_url}}/api/users/{{flow.userId}}

Headers:

Authorization: Bearer {{flow.token}}

Body:

{"displayName": "Updated Name"}

Assertions:

✓ Status code equals 200

✓ Body JSON data.displayName equals Updated Name

Key takeaway: {{base_url}}, {{email}}, and {{password}} come from the group environment (static, reusable). {{flow.token}}, {{flow.userId}}, and {{flow.username}} come from response extractions (dynamic, per-run).

Example: Order Management Flow

A 4-step CRUD flow that creates an order, retrieves it, updates the quantity, and finally cancels it. Demonstrates the Setup → Test → Teardown pattern.

POSTStep 1: Create Order

URL: {{base_url}}/api/orders

Headers: Authorization: Bearer {{flow.token}}

Body:

{"productId": "prod_123", "quantity": 2, "shippingAddress": {"city": "Istanbul", "country": "TR"}}

Extractions:

NameSourceExpression
orderIdJSON Pathdata.id
orderStatusJSON Pathdata.status

Assertions: Status code equals 201

GETStep 2: Get Order Details

URL: {{base_url}}/api/orders/{{flow.orderId}}

Headers: Authorization: Bearer {{flow.token}}

Assertions:

✓ Status code equals 200

✓ Body JSON data.id equals {{flow.orderId}}

✓ Body JSON data.status equals pending

✓ Body JSON data.quantity equals 2

PATCHStep 3: Update Quantity

URL: {{base_url}}/api/orders/{{flow.orderId}}

Headers: Authorization: Bearer {{flow.token}}

Body:

{"quantity": 5}

Assertions:

✓ Status code equals 200

✓ Body JSON data.quantity equals 5

DELETEStep 4: Cancel Order (Teardown)

URL: {{base_url}}/api/orders/{{flow.orderId}}

Headers: Authorization: Bearer {{flow.token}}

Assertions: Status code equals 200 or 204

Key takeaway: The {{flow.token}} here is assumed to come from a previous Auth flow run, or from a Login step you add at the beginning. In a real setup, you'd either prepend a Login step or use tg.flow.set() in a pre-script to set the token. The last step (Cancel) acts as teardown to keep the database clean for re-runs.

Example: Payment Processing Flow

A 3-step flow that creates a payment intent, confirms the payment, and verifies the final state. Shows how multiple extractions chain through the flow.

POSTStep 1: Create Payment Intent

URL: {{base_url}}/api/payments/intent

Headers: Authorization: Bearer {{flow.token}}

Body:

{"amount": 9999, "currency": "usd", "orderId": "{{flow.orderId}}"}

Extractions:

NameSourceExpression
paymentIdJSON Pathdata.id
clientSecretJSON Pathdata.clientSecret

Assertions: Status code equals 201, Body JSON data.status equals requires_confirmation

POSTStep 2: Confirm Payment

URL: {{base_url}}/api/payments/{{flow.paymentId}}/confirm

Headers: Authorization: Bearer {{flow.token}}

Body:

{"clientSecret": "{{flow.clientSecret}}"}

Extractions:

NameSourceExpression
transactionIdJSON Pathdata.transactionId

Assertions: Status code equals 200, Body JSON data.status equals succeeded

GETStep 3: Verify Payment

URL: {{base_url}}/api/payments/{{flow.paymentId}}

Headers: Authorization: Bearer {{flow.token}}

Assertions:

✓ Status code equals 200

✓ Body JSON data.status equals succeeded

✓ Body JSON data.amount equals 9999

✓ Body JSON data.transactionId equals {{flow.transactionId}}

Key takeaway: Notice how data chains through: Step 1 extracts paymentId and clientSecret, Step 2 uses both and extracts transactionId, Step 3 verifies using paymentId from Step 1 and transactionId from Step 2. Each step builds on the data from previous steps.

Flow Organization

  • Group by domain: Create flow groups per API or service (e.g., "Auth API", "Payment API", "User API")
  • Name flows descriptively: Use action-oriented names like "User Registration Flow" or "Order Checkout Sequence" instead of generic names
  • Name steps clearly: Each step name should describe its purpose (e.g., "Create User" instead of "Step 1")
  • Keep flows focused: A flow should test one scenario or workflow. Prefer multiple small flows over one large flow.

Variable Strategy

  • Use {{flow.varName}} for dynamic data: Tokens, IDs, timestamps, and anything that comes from a response should use the flow prefix
  • Use {{varName}} for config: Base URLs, API keys, and static configuration belong in group environments
  • Extract early: Set up extractions in the first steps that produce values needed later (e.g., auth tokens, resource IDs)
  • Use meaningful names: Name variables based on their purpose — authToken instead of var1
  • Prefer JSON Path: For structured JSON responses, JSON Path extraction is the most reliable and readable
  • Use regex sparingly: Reserve regex extraction for non-JSON responses or complex patterns that JSON Path can't handle

Environment Usage

  • Use environments for base URLs: Store {{base_url}} in environments so the same flow works against dev, staging, and production
  • Mark secrets as secret: Always use the secret flag for API keys, passwords, and tokens to prevent accidental exposure
  • Store test credentials: Keep test user credentials (email, password) in environments so flows are rerunnable without editing steps

Linear vs Visual Mode

ScenarioRecommended ModeWhy
Simple API sequenceLinearSteps run in order, no branching needed
CRUD test suiteLinearCreate → Read → Update → Delete is naturally sequential
Conditional logicVisualBranch based on response status or data
Parallel requestsVisualIndependent branches execute concurrently
Complex workflowVisualEasier to understand flow structure at a glance

Execution Tips

  • Test steps individually first: Use the Send button on each step to verify it works before running the entire flow
  • Use "Stop on Failure" during development: This helps you find and fix the first broken step without noise from subsequent failures
  • Disable "Stop on Failure" for regression: When running regression tests, let all steps execute to get the full picture of what's passing and failing
  • Use iterations for stability: Run 5-10 iterations to catch intermittent failures or performance regressions
  • Add delays for rate-limited APIs: If an API has rate limits, use the delay option to space out requests

Step Design

  • One action per step: Each step should do one thing. Don't try to combine multiple operations into a single request.
  • Add assertions: Use the Processors tab to add assertions that validate response status, body content, and headers. This turns your flows into automated tests.
  • Configure retries for flaky endpoints: If a step calls an unreliable service, set up retry behavior instead of re-running the entire flow.
  • Disable non-essential steps: Use the enable/disable toggle to temporarily skip steps during debugging without deleting them.