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

# Who may pass

> A gate always asks. Two levers decide who it lets through: how often each person may pass, and how long their BotShield ID has been real.

Every BotShield gate asks. Each pass is a new passkey confirmation on the person's phone, on a Human Gate and on an Age Gate, whether or not you have seen the person before. There is no instant pass and no window in which an earlier confirmation still counts.

What you choose is **who may pass**. A gate has two levers. Both are off by default: anyone may pass, as often as they like.

## The two levers

| Lever | What you set | What it does |
| - | - | - |
| **Let each person pass** | `1`–`100` times **a day**, **a week**, **every 30 days** or **ever**, or **as often as they like** | Limits how many times one person can pass this gate in the window. |
| **BotShield ID real for at least** | `0`–`365` days. `0` means no requirement. | Lets a person pass only when their BotShield ID has proved they are a person on at least that many different days. |

Use them together. A sign-up gate might allow **1 per person, ever**. A limited drop might allow **1 per person a day** for a BotShield ID real for **30+ days**.

### How passes are counted

* **Per person, at this gate.** BotShield counts the person, not the account they use with you. Two accounts held by one person share one count. The count uses a private key that BotShield derives for your platform. It never leaves BotShield, and it is not a value you can read.
* **Every pass is recorded**, even while the lever is off. A limit you set later counts the passes already made in its window.
* **One request counts once.** A double tap on the same request does not use two passes.

### How real days are counted

A **real day** is a day on which the person's BotShield ID completed a passkey confirmation, at any gate on any platform. BotShield counts distinct days, not confirmations, and today's confirmation counts. You never receive the number. You only learn whether the person met your bar.

## Set the levers

<Steps>
  <Step title="Open the gate">
    In the [Console](https://console.botshield.ai), open **BotShield Gate** and select the gate. **Who may pass** sits in the **Configuration** card, under the gate type.
  </Step>

  <Step title="Set the sentence">
    Read it as one line: *Let each person pass* `1` *time* `a day`. *BotShield ID real for at least* `30` *days.*
  </Step>

  <Step title="Save">
    Select **Save**. On a Production gate, confirm with your [Developer passkey](/gate/go-to-production#3-create-your-developer-passkey). The Console shows the saved version, for example "Saved · version 3".
  </Step>
</Steps>

Only organization admins can change the levers. Members can read them.

<Note>
  Each save writes a new version of the gate's policy. Nothing is edited in place, so the history of a gate's rules is kept. Your organization can also hold a policy that applies to every gate. A gate's own levers can only make that policy stricter, never looser: the stricter pass limit and the higher real-days bar win.
</Note>

## When a lever refuses someone

A refusal is **Unavailable** with a name. Your code still branches on the two [result states](/concepts/result-states). The name tells you which message to show.

| Name | Meaning |
| - | - |
| `pass_limit_reached` | This person has used their passes at this gate for the window. |
| `real_days_not_met` | This person's BotShield ID has not been real for enough days yet. |

BotShield refuses at one of two moments:

* **Before the passkey step**, when BotShield already knows the person. This happens when they have [secured their account](/secured-accounts/overview) with you and your page sends their `platform-user-ref`. The person is not asked to confirm for a pass they cannot use.
* **After the passkey step**, for everyone else. The person confirms, then BotShield checks the levers before it issues a token. No token is issued for a refused pass.

Where you see the name:

| Surface | Before the passkey step | After the passkey step |
| - | - | - |
| `botshield:failure` | `reason: "blocked"`, plus `failure_code` and a `message` on widget 3.0.12 and later | `reason` is the name, for example `"pass_limit_reached"` |
| `GET /verification/status` | — | `status: "failed"`, `reason` is the name |
| `gate.unavailable` webhook | — | `reason: "internal_error"`, `failure_code` is the name |

```json theme={null}
{
  "type": "gate.unavailable",
  "event_id": "req_3f9a1c…",
  "request_id": "req_3f9a1c…",
  "failed_at": "2026-10-13T17:05:40.000Z",
  "verdict": "unavailable",
  "reason": "internal_error",
  "failure_code": "pass_limit_reached",
  "error_message": "This gate lets each person pass once a day.",
  "environment": "production",
  "product": "census"
}
```

Show the person a plain line and a way forward: "You've reached this site's limit for now. Try again later." or "Your BotShield ID is too new for this site. Try again in a few days." Never treat a refusal as proof of a bot.

## Next steps

<CardGroup cols={2}>
  <Card title="Place a gate" icon="location-dot" href="/gate/place-a-gate">
    Place, configure and activate a gate.
  </Card>

  <Card title="Result states" icon="circle-check" href="/concepts/result-states">
    Verified and Unavailable, and how to design for both.
  </Card>

  <Card title="Testing" icon="flask" href="/gate/testing">
    Trigger both refusals in the Sandbox.
  </Card>

  <Card title="BotShield ID" icon="id-badge" href="/concepts/botshield-id">
    What a BotShield ID is, and what you never see of it.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.