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

# Pre-Tier Requests by IP Address

> Use existing customer data and your service's pricing model to apply the proper rate limit to a user's IP address.

export const domain_0 = undefined

If you have a public API that your customers integrate into their software or services, you'll want to implement a rate limiting policy to prevent misuse, ensure fair access for all users, and prevent heavy load from slowing down your entire infrastructure.
Based on your packaging and pricing model, you may also need to implement different rate limit limits for customers based on their "tier" and how much they pay.

ngrok and Traffic Policy let you validate an incoming user's request against identity or CRM services with data about their tier and selectively apply the proper rate limits to their IP address.

## 1. Create endpoints for your services

Start an internal [Agent Endpoint](/gateway/agent-endpoints/), replacing `$PORT` based on where your upstream service listens.
You can also use one of the [SDKs](/agent-sdks) or the [Kubernetes Operator](/k8s).

```bash theme={null}
ngrok http $PORT --url https://service.internal
```

Start a second endpoint for your identity service.

```bash theme={null}
ngrok http $PORT --url https://id.internal
```

## 2. Reserve a domain

Navigate to the [**Domains** section](https://dashboard.ngrok.com/domains) of the ngrok dashboard and click **New +** to reserve a free static domain like {<code>{domain_0}</code> || `https://your-service.ngrok.app`} or a [custom domain](/gateway/custom-domains/) you already own.

We'll refer to this domain as `$NGROK_DOMAIN` from here on out.

## 3. Create a Cloud Endpoint

Navigate to the [**Endpoints** section](https://dashboard.ngrok.com/endpoints?sortBy=updatedAt\&orderBy=desc) of the ngrok dashboard, then click **New +** and **Cloud Endpoint**.

In the **URL** field, enter the domain you just reserved to finish creating your [Cloud Endpoint](/gateway/cloud-endpoints/).

## 4. Validate requests against your internal identity service with Traffic Policy

While viewing your new Cloud Endpoint in the dashboard, copy the policy below and paste it into the Traffic Policy editor.
You'll need to change:

* `https://id.internal/api/user`: Replace the path according to your identity service's API.
* `$ID_API_TOKEN`: Replace with an API key or other authentication method generated by your identity service.
* `{ "user": "${req.headers['Authorization']}" }`: Replace with an appropriate body based on how your user's requests are structured.

```yaml theme={null}
on_http_request:
  - actions:
      - type: http-request
        config:
          url: https://id.internal/api/user
          method: POST
          headers:
            Authorization: "Bearer $ID_API_KEY"
            Content-Type: "application/json"
          body: |
            { "token": "${req.headers['Authorization']}" }

  # If the request failed, short-circuit the request with an error response.
  - expressions:
      - "actions.ngrok.http_request.res.status_code < '200' &&
        actions.ngrok.http_request.res.status_code >= '300'"
    actions:
      - type: custom-response
        config:
          headers:
            content-type: application/json
          body: |
            { "message": "Request failed: ${actions.ngrok.http_request.res.status_code}" }

  # If the request was successful, capture the value of the user's tier for reuse.
  - expressions:
      - "actions.ngrok.http_request.res.status_code == 200"
    actions:
      - type: set-vars
        config:
          vars:
            tier: json.decode(actions.ngrok.http_request.res.body).tier.value

  # Check the user's tier based on the variable and apply the rate limit.
  - expressions:
      - "vars.tier == 'bronze'"
    actions:
      - type: rate-limit
        config:
          name: BronzeLimit
          algorithm: sliding_window
          capacity: 30
          rate: 60s
          bucket_key:
            - conn.client_ip

  - expressions:
      - "vars.tier == 'silver'"
    actions:
      - type: rate-limit
        config:
          name: SilverLimit
          algorithm: sliding_window
          capacity: 100
          rate: 60s
          bucket_key:
            - conn.client_ip

  - expressions:
      - "vars.tier == 'gold'"
    actions:
      - type: rate-limit
        config:
          name: GoldLimit
          algorithm: sliding_window
          capacity: 1000
          rate: 60s
          bucket_key:
            - conn.client_ip

  - actions:
      - type: forward-internal
        config:
          url: https://service.internal
```

**What's happening here?**
This policy first sends an authenticated HTTP request to your internal identity/CRM service at `https://id.internal`.
This request's body contains the `Authorization` token your user added as a header to their request.

If your identity service responds with a `400`-level error code, the policy short-circuits the request and responds with a custom error response. If your identity service responds with a `200` error code, then the policy saves the user's tier as a `vars.tier` variable.

The policy then applies different rate limiting capacities to the user's IP address based on the `tier` data stored in your identity service. Finally, the policy forwards the authenticated and rate limited request to your upstream service.

## Try out your endpoint

Visit the domain you reserved either in the browser or in the terminal using a tool like `curl`.
You should see the app or service at the port connected to your internal Agent Endpoint.

## What's next?

* Explore other examples of using the [`http-request`](/traffic-policy/actions/http-request/#examples) and [`forward-internal`](/traffic-policy/actions/forward-internal/#examples) Traffic Policy actions.
* View your traffic in [Traffic
  Inspector](https://dashboard.ngrok.com/traffic-inspector) to understand how requests flow into your identity service and watch error rates for potential issues, which may influence how you tweak the [retry logic and timeout behavior](/traffic-policy/actions/http-request/#retry-logic) of your `http-request` action.
