HTTP Plugin
Test HTTP APIs with full request/response validation and OpenAPI contract support.
Quick Start
tests:
  - name: "Create user"
    steps:
      - name: "POST request"
        plugin: http
        config:
          method: POST
          url: "https://api.example.com/users"
          headers:
            Content-Type: "application/json"
          body: |
            {
              "name": "Test User",
              "email": "test@example.com"
            }
        assertions:
          - type: status_code
            expected: 201
        save:
          - json_path: ".id"
            as: "user_id"
Configuration
Required Fields
| Field | Description | Example | 
|---|---|---|
method | 
HTTP method | GET, POST, PUT, DELETE, PATCH | 
url | 
Request URL | https://api.example.com/users | 
Optional Fields
| Field | Description | Example | 
|---|---|---|
headers | 
HTTP headers | {"Authorization": "Bearer token"} | 
body | 
Request body (string) | {"key": "value"} | 
form | 
URL-encoded form data | {"username": "test"} | 
openapi | 
OpenAPI validation config | See OpenAPI Validation | 
Request Chaining
Save values from one request and use them in subsequent requests:
steps:
  # Step 1: Create resource
  - name: "Create car"
    plugin: http
    config:
      method: POST
      url: "https://api.example.com/cars"
      body: |
        {
          "make": "Toyota",
          "model": "Corolla"
        }
    save:
      - json_path: ".id"
        as: "car_id"
      - header: "server"
        as: "server_info"
  # Step 2: Use saved values
  - name: "Get car"
    plugin: http
    config:
      method: GET
      url: "https://api.example.com/cars/{{ car_id }}"
Assertions
Validate responses with multiple assertion types:
Status Code
JSON Path
assertions:
  - type: json_path
    path: ".user.email"
    expected: "test@example.com"
  - type: json_path
    path: ".items | length"
    expected: 3
Headers
Save Fields
Extract values from responses for use in later steps:
From JSON Response
From Headers
OpenAPI Validation
Validate requests and responses against OpenAPI v3 contracts.
Suite-Level Configuration
Apply OpenAPI validation to all HTTP steps:
openapi:
  spec: "./contracts/api.yaml"  # Local file or HTTP(S) URL
  cache_ttl: "30m"              # Contract cache duration
  validate_request: true        # Validate outgoing requests
  validate_response: true       # Validate incoming responses
tests:
  - name: "API test"
    steps:
      - plugin: http
        config:
          method: POST
          url: "https://api.example.com/users"
          body: '{"name": "Test"}'
        # Inherits suite-level OpenAPI validation
Step-Level Overrides
Override validation for specific steps:
- name: "Test malformed payload"
  plugin: http
  config:
    method: POST
    url: "https://api.example.com/users"
    body: '{"invalid": "data"}'
    openapi:
      validate_request: false  # Skip request validation for this step
OpenAPI Options
| Field | Description | Example | 
|---|---|---|
spec | 
Path or URL to OpenAPI document | ./api.yaml or https://api.example.com/spec | 
cache_ttl | 
Contract cache duration | 30m (default) | 
version | 
Version identifier to force cache refresh | "2024-03-15" | 
validate_request | 
Enable request validation | true | 
validate_response | 
Enable response validation | true | 
operation_id | 
Require specific operation | "createUser" | 
Form Data
Submit URL-encoded forms:
- name: "Login form"
  plugin: http
  config:
    method: POST
    url: "https://app.example.com/login"
    form:
      username: "test@example.com"
      password: "testpass"
Note: If both form and body are provided, form takes precedence.
Common Patterns
CRUD Operations
steps:
  # Create
  - name: "Create"
    plugin: http
    config:
      method: POST
      url: "{{ .vars.base_url }}/users"
      body: '{"name": "Test"}'
    save:
      - json_path: ".id"
        as: "user_id"
  # Read
  - name: "Read"
    plugin: http
    config:
      method: GET
      url: "{{ .vars.base_url }}/users/{{ user_id }}"
  # Update
  - name: "Update"
    plugin: http
    config:
      method: PUT
      url: "{{ .vars.base_url }}/users/{{ user_id }}"
      body: '{"name": "Updated"}'
  # Delete
  - name: "Delete"
    plugin: http
    config:
      method: DELETE
      url: "{{ .vars.base_url }}/users/{{ user_id }}"
Authentication
steps:
  - name: "Login"
    plugin: http
    config:
      method: POST
      url: "{{ .env.API_URL }}/auth/login"
      body: |
        {
          "email": "{{ .env.TEST_EMAIL }}",
          "password": "{{ .env.TEST_PASSWORD }}"
        }
    save:
      - json_path: ".token"
        as: "auth_token"
  - name: "Authenticated request"
    plugin: http
    config:
      method: GET
      url: "{{ .env.API_URL }}/me"
      headers:
        Authorization: "Bearer {{ auth_token }}"
Query Parameters
- name: "Search with filters"
  plugin: http
  config:
    method: GET
    url: "{{ .vars.api_url }}/search?q=test&limit=10&offset=0"
See Also
- Variables - Using environment, config, and runtime variables
 - Retry Policies - Retrying failed HTTP requests