> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/grafana/k6/llms.txt
> Use this file to discover all available pages before exploring further.

# HTTP Testing

> Test HTTP/1.1 and HTTP/2 APIs with k6's comprehensive HTTP module

k6 provides full support for HTTP/1.1 and HTTP/2 protocols, enabling you to test REST APIs, web services, and HTTP endpoints with a rich set of methods and configuration options.

## HTTP Methods

k6 supports all standard HTTP methods through the `k6/http` module.

<CodeGroup>
  ```javascript Simple GET Request theme={null}
  import http from 'k6/http';

  export default function () {
    http.get('https://quickpizza.grafana.com');
  }
  ```

  ```javascript All HTTP Methods theme={null}
  import http from "k6/http";
  import { check, group } from "k6";

  export default function() {
    // GET request
    group("GET", function() {
      let res = http.get("http://httpbin.org/get?verb=get");
      check(res, {
        "status is 200": (r) => r.status === 200,
        "is verb correct": (r) => r.json().args.verb === "get",
      });
    });

    // POST request
    group("POST", function() {
      let res = http.post("http://httpbin.org/post", { verb: "post" });
      check(res, {
        "status is 200": (r) => r.status === 200,
        "is verb correct": (r) => r.json().form.verb === "post",
      });
    });

    // PUT request
    group("PUT", function() {
      let res = http.put(
        "http://httpbin.org/put",
        JSON.stringify({ verb: "put" }),
        { headers: { "Content-Type": "application/json" }}
      );
      check(res, {
        "status is 200": (r) => r.status === 200,
        "is verb correct": (r) => r.json().json.verb === "put",
      });
    });

    // PATCH request
    group("PATCH", function() {
      let res = http.patch(
        "http://httpbin.org/patch",
        JSON.stringify({ verb: "patch" }),
        { headers: { "Content-Type": "application/json" }}
      );
      check(res, {
        "status is 200": (r) => r.status === 200,
        "is verb correct": (r) => r.json().json.verb === "patch",
      });
    });

    // DELETE request
    group("DELETE", function() {
      let res = http.del("http://httpbin.org/delete?verb=delete");
      check(res, {
        "status is 200": (r) => r.status === 200,
        "is verb correct": (r) => r.json().args.verb === "delete",
      });
    });
  }
  ```
</CodeGroup>

## HTTP/2 Support

k6 automatically handles HTTP/2 connections when the server supports it. You can verify the protocol version in your tests.

```javascript theme={null}
import http from "k6/http";
import { check } from "k6";

export default function () {
  check(http.get("https://quickpizza.grafana.com"), {
    "status is 200": (r) => r.status == 200,
    "protocol is HTTP/2": (r) => r.proto == "HTTP/2.0",
  });
}
```

## Authentication

<Tabs>
  <Tab title="Basic Auth">
    k6 supports HTTP Basic Authentication through URL credentials or custom headers.

    ```javascript theme={null}
    import encoding from "k6/encoding";
    import http from "k6/http";
    import { check } from "k6";

    export default function() {
      // Method 1: Username and password in URL
      let res = http.get("http://user:passwd@httpbin.org/basic-auth/user/passwd");

      check(res, {
        "status is 200": (r) => r.status === 200,
        "is authenticated": (r) => r.json().authenticated === true,
        "is correct user": (r) => r.json().user === "user"
      });

      // Method 2: Authorization header
      res = http.get(
        "http://httpbin.org/basic-auth/user/passwd",
        {
          headers: {
            "Authorization": "Basic " + encoding.b64encode("user:passwd")
          }
        }
      );

      check(res, {
        "status is 200": (r) => r.status === 200,
        "is authenticated": (r) => r.json().authenticated === true,
      });
    }
    ```
  </Tab>

  <Tab title="Bearer Token">
    ```javascript theme={null}
    import http from "k6/http";

    export default function() {
      const token = "your-api-token";
      const params = {
        headers: {
          "Authorization": `Bearer ${token}`,
        },
      };

      http.get("https://api.example.com/data", params);
    }
    ```
  </Tab>
</Tabs>

## Batch Requests

Perform multiple HTTP requests in parallel for improved performance.

```javascript theme={null}
import { check } from 'k6';
import http from 'k6/http';

export default function() {
  const responses = http.batch([
    "https://quickpizza.grafana.com/test.k6.io",
    "https://quickpizza.grafana.com/pi.php"
  ]);

  check(responses[0], {
    "main page 200": res => res.status === 200,
  });

  check(responses[1], {
    "pi page 200": res => res.status === 200,
    "pi page has right content": res => res.body === "3.14",
  });
}
```

<Note>
  Batch requests are executed in parallel and wait for all requests to complete before continuing.
</Note>

## Request Parameters

Configure HTTP requests with various parameters:

```javascript theme={null}
import http from "k6/http";

export default function() {
  const params = {
    headers: {
      "Content-Type": "application/json",
      "X-Custom-Header": "value",
    },
    tags: {
      name: "MyRequest",
    },
    timeout: "60s",
    redirects: 5,
    cookies: {
      session: "session-id-value",
    },
  };

  http.post(
    "https://api.example.com/endpoint",
    JSON.stringify({ key: "value" }),
    params
  );
}
```

## Response Object

HTTP responses provide comprehensive information about the request:

| Property      | Description                                     |
| ------------- | ----------------------------------------------- |
| `status`      | HTTP status code                                |
| `status_text` | HTTP status text                                |
| `proto`       | Protocol version (e.g., "HTTP/1.1", "HTTP/2.0") |
| `headers`     | Response headers as object                      |
| `body`        | Response body as string                         |
| `json()`      | Parse response body as JSON                     |
| `cookies`     | Response cookies                                |
| `timings`     | Request timing information                      |
| `error`       | Error message (if request failed)               |
| `error_code`  | Error code (if request failed)                  |

## TLS Configuration

k6 provides constants for configuring TLS connections:

```javascript theme={null}
import http from "k6/http";

export const options = {
  tlsVersion: {
    min: http.TLS_1_2,
    max: http.TLS_1_3,
  },
};

export default function() {
  http.get("https://api.example.com");
}
```

### Available TLS Constants

* `http.TLS_1_0`
* `http.TLS_1_1`
* `http.TLS_1_2`
* `http.TLS_1_3`

## Cookie Management

Manage cookies across requests with cookie jars:

```javascript theme={null}
import http from "k6/http";

export default function() {
  // Cookies are automatically maintained across requests
  const jar = http.cookieJar();
  
  jar.set("https://example.com", "session", "value");
  
  http.get("https://example.com/authenticated");
}
```

## Async Requests

k6 supports asynchronous HTTP requests using promises:

<Warning>
  Async requests are an experimental feature and may not be suitable for all use cases.
</Warning>

```javascript theme={null}
import http from "k6/http";

export default async function() {
  const response = await http.asyncRequest(
    "GET",
    "https://api.example.com/data"
  );
  console.log(response.status);
}
```

## Best Practices

1. **Use batch requests** for parallel operations to improve test efficiency
2. **Set appropriate timeouts** to prevent hanging requests
3. **Verify protocol versions** when testing HTTP/2 support
4. **Use tags** to organize and filter metrics
5. **Check response status** before parsing JSON to avoid errors
6. **Reuse connections** by making multiple requests in the same VU iteration

## Related Resources

* [HTTP API Reference](/protocols/http)
* [Thresholds](/concepts/thresholds)
* [Checks](/concepts/checks)
