> ## Documentation Index
> Fetch the complete documentation index at: https://docs.roolink.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Capture requests with powhttp

> Record what Chrome really sends to your target, copy it, and prove your own client sends the same thing.

Bot protection judges your connection and your headers before it reads anything you send. The only reliable source for what those should look like is a real Chrome talking to the real site, recorded on the wire. powhttp does that recording, and it records your own script the same way, so you can put the two side by side.

Everything on this page is a one-time setup per target. Once your script matches Chrome, it stays matched until Chrome or the site changes.

<Note>
  Do not read header order from Chrome DevTools. DevTools sorts headers alphabetically, which is not the order Chrome sends them in. Only a wire capture shows the true order.
</Note>

## Install and trust the certificate

<Steps>
  <Step title="Install powhttp">
    Download it from [powhttp.com](https://powhttp.com). It is free while in beta and runs on Windows, macOS and Linux. It manages the system proxy and certificate for you, so there is nothing to configure by hand.
  </Step>

  <Step title="Trust the root certificate">
    Click **Trust Root Certificate** in powhttp. It generates a certificate and adds it to your system's trust store. Without this step HTTPS traffic stays encrypted and you will see connections but no headers.
  </Step>
</Steps>

## Record Chrome on the target

<Steps>
  <Step title="Start a recording">
    Start recording in powhttp, then open Chrome. Because powhttp set the system proxy, Chrome's traffic flows through it automatically.
  </Step>

  <Step title="Walk through the flow like a user">
    Load the page a person would start on, then do the protected action once: add to cart, search, log in. Stop recording.
  </Step>

  <Step title="Find the three requests that matter">
    For an Akamai site: the page load, the Akamai script load, and the sensor post to the script path. For other products the guide names its own requests. Open each one and note the headers exactly as listed, top to bottom.
  </Step>
</Steps>

## Copy the headers into your code

Each request type has its own header list, and the order is part of the fingerprint. Copy each list into your code in the order powhttp shows it. Only the values tied to the site change: the host, the referer and the origin. The User-Agent stays identical to the one Roolink will receive.

In Go with tls-client, set `http.HeaderOrderKey` to the same order. In Node with tlsclientwrapper, pass `headerOrder` with the request. In Python with Python-Tls-Client, set the session's `header_order` before the request. Without an explicit order these clients may send headers in any order, so always set it. [Set up your HTTP client](/http-client) has a `send` helper for each language that does this on every request.

## Record your own script and compare

<Steps>
  <Step title="Route your script through powhttp">
    Point your script's proxy at the address powhttp shows in its window instead of your sticky proxy. powhttp can also export the proxy environment variables for you, which is the simplest way for a script launched from a terminal.

    Your TLS client must trust powhttp's certificate while you capture. Most clients read the system trust store, which the earlier step populated. If yours does not, disable certificate verification for the capture run only.
  </Step>

  <Step title="Run the same flow">
    Run your script against the same page and action you recorded in Chrome.
  </Step>

  <Step title="Compare request by request">
    Open Chrome's request and your script's request for the same step and read them together. They should differ only in cookies and in the values that legitimately change. Check, in this order: header names and their order, the `sec-fetch-*` and `sec-ch-ua*` values, the content type on posts, and the TLS handshake powhttp shows for each connection.
  </Step>
</Steps>

<Warning>
  While your script runs through powhttp it is not using your sticky proxy, so the site sees your own IP. Use these runs to compare requests, not to judge whether the site blocks you. Switch the proxy back before a real run.
</Warning>

## What you are looking for

| Difference you see                                      | What it means                                                                                   |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| Headers in a different order                            | Your HTTP library is reordering them. Use a TLS client and set the order explicitly.            |
| A header Chrome sends that you do not                   | Add it, in position. `sec-fetch-*` and `priority` are the ones most often missing.              |
| A header you send that Chrome does not                  | Remove it. `Connection: keep-alive` and library default `Accept` values are the usual culprits. |
| Different `sec-ch-ua` major version from the User-Agent | Your client hints and User-Agent describe different browsers. Fix both to the same version.     |
| Different TLS handshake                                 | Wrong client profile. Use the newest Chrome profile your TLS client offers.                     |

When the two recordings match, move on. If the site still refuses your request, the cause is elsewhere: the proxy, the payload, or a second protection layer. [Troubleshoot a block](/troubleshoot) matches the symptom to the layer.
