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

# Firewalls and bot protection

> Let ZeroClick's signed forwards through a WAF, CDN, or bot-protection layer in front of your API without weakening the guard.

ZeroClick forwards every paid request, and every unpaid probe, from its own servers to your upstream base URL. A firewall, CDN, or bot-protection layer in front of that URL sees automated traffic from a cloud provider's address space with no browser behind it, which is what bot protection exists to challenge. This page covers what a challenge does to a purchase and how to exempt ZeroClick's forwards without opening those paths to anyone else.

## What a challenge does to a purchase

Bot protection answers a request it distrusts with a challenge in place of your response: usually a `403` carrying an HTML page (Vercel's Security Checkpoint, Cloudflare's "Just a moment" interstitial) that a browser passes by running JavaScript. ZeroClick does not solve challenges. It returns your upstream's status and body to the buyer unchanged, so the agent receives an HTML checkpoint where it expected a `402` or your JSON, and reports the purchase as failed. Nothing on your side records an error, because the request never reached your handler.

Signs that this is happening:

* An agent reports a security checkpoint, a bot check, or a `403` from your pay URL on a route that answers JSON.
* The failures are intermittent. One probe passes, the next is challenged.
* Your own logs show no request for the failed call.

Volume makes it more likely. ZeroClick forwards a signed anonymous probe for every unpaid pay-as-you-go call, then the paid retry, and it probes each endpoint when it builds your catalog. To a bot detector, a busy storefront looks like a scripted flood from one place.

## What to key the exemption on

| Property of a forward | Usable | Why                                                                                                                                                                                                                   |
| --------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `zc-signature` header | Yes    | Present on every forward: paid retries, anonymous probes, catalog probes, and account endpoint calls. ZeroClick strips inbound `zc-*` headers, so only ZeroClick sets it on requests that arrive through the pay URL. |
| Source IP             | No     | ZeroClick publishes no fixed egress range. Its addresses are shared cloud addresses that can change without notice.                                                                                                   |
| `User-Agent`          | No     | ZeroClick passes the buyer's own `User-Agent` through unchanged, so there is no ZeroClick user agent to allow.                                                                                                        |

Match on the presence of `zc-signature`, and scope the rule to the paths ZeroClick calls: the endpoint paths in your catalog, which are the paths agents request on your pay URL and which ZeroClick forwards to the origin of your upstream base URL, plus `/zeroclick/access` and everything under it if you [sell accounts and API keys](/integrate/stateful-sellers). The rest of your site keeps its protection.

One fetch carries no signature: the OpenAPI document ZeroClick downloads from your store's OpenAPI URL when it imports your catalog. If that document sits behind the same challenge, exempt its path on its own. It is public by design.

## Why the exemption is safe

Anyone can put a `zc-signature` header on a request, so the rule lets unverified traffic past the bot check on the exempted paths. That traffic then meets your guard, which recomputes the HMAC with your signing secret and answers `401 {"error":"invalid_zeroclick_signature"}` before your handler runs. A forged header trades a challenge page for a 401 and nothing more. The guard was always the gate. The exemption stops a second gate from refusing the traffic the first one was built to check. See [verify requests](/integrate/verify-requests).

Rate limits are a different control. One sized for real buyer volume can stay in place. A challenge action cannot, because no forward can pass it.

## Platform recipes

<Tabs>
  <Tab title="Vercel">
    Vercel's Bot Protection managed ruleset challenges non-browser traffic, and Vercel notes that direct API calls cannot pass the challenge. Its documented exemption for trusted automation is a WAF custom rule with the **Bypass** action.

    1. In the project, open **Firewall**, then **Configure**, then **Add New** and **Rule**.
    2. Add the condition **Header** `zc-signature` **Exists**. Add a second condition with **AND**: **Request Path** **Starts with** the path ZeroClick calls, for example `/api/`.
    3. Set the action to **Bypass**, save the rule, and publish the change. If you have Challenge rules of your own, place this rule above them. Custom rules run in order, and the managed rulesets run after them.

    Bypass skips the remaining custom rules and the managed rulesets, including Bot Protection. It does not skip system-level DDoS mitigation. **Attack Mode** is separate: it challenges every request that is not a verified bot or a call from your own Vercel Functions and Cron Jobs, and Vercel does not list custom Bypass rules among its exemptions. Leave Attack Mode off while you sell through ZeroClick.
  </Tab>

  <Tab title="Cloudflare">
    Create a WAF custom rule with the **Skip** action, placed above any rule that challenges:

    ```text Expression theme={null}
    any(http.request.headers.names[*] == "zc-signature") and starts_with(http.request.uri.path, "/api/")
    ```

    Under **Then**, choose **Skip** and select **All Super Bot Fight Mode rules**. Select **Browser Integrity Check** as well if the zone has it enabled, and **All remaining custom rules** if you have challenge rules of your own below this one.

    A Skip rule cannot exempt traffic from Bot Fight Mode, the Free plan's version. If the zone runs Bot Fight Mode, turn it off under **Security**, then **Settings**, filtered to **Bot traffic**, or move to a plan with Super Bot Fight Mode so the Skip rule applies. Under Attack mode is separate too. It challenges every visitor, so scope it with a Configuration Rule that sets a lower Security Level on the paths ZeroClick calls.
  </Tab>

  <Tab title="Other layers">
    Any WAF that can allow a request on a header condition works the same way: AWS WAF (an allow rule on the `zc-signature` header, ordered above Bot Control), Google Cloud Armor, Fastly, or a challenge module in nginx. Match on the header's presence, scope to the ZeroClick paths, and keep the guard as the gate. A layer that can only allow by IP address cannot exempt ZeroClick. Take the challenge off the API paths instead.
  </Tab>
</Tabs>

## Confirm the rule

From outside your network, send a request with a made-up signature to a guarded route:

```sh theme={null}
curl -i https://api.acme.com/v1/product-watch \
  -H "zc-signature: t=0,kid=hsec_probe,v1=0"
```

The right answer is the guard's `401 {"error":"invalid_zeroclick_signature"}`: the request passed the firewall and verification refused it. A `403` or an HTML body means the challenge still applies. Then send an unpaid request to the same route on your pay URL. A `402` with a payment challenge confirms the probe reached your guard.
