URL: /products/metering

---
title: Metering
description: Rate limit your AI endpoint by real abuse, not IP counts. FormShield Metering caps cost on LLM and public routes and catches multi-account abuse. Coming soon.
---

<Note>
  Metering is **coming soon**. The `POST /v1/meter` endpoint is in development and not yet live. Join the early-access waitlist from the [dashboard](https://formshield.dev/app) to try it on your endpoints and help shape the limit and budget model.
</Note>

Rate-limit your AI endpoint by abuse, not IPs. Wrap any public or LLM-powered route, set a limit, and let FormShield catch multi-account abuse and cap the bill before it runs away.

## The problem

A single abuser cycling IPs, keys, or throwaway accounts can blow past per-IP rate limits and run your token bill into the ground overnight. Naive rate limiting either throttles real users or misses the distributed abuse that actually costs you money on LLM-backed routes.

Metering targets that failure mode directly: it correlates the caller across IPs, sessions, and accounts to detect one actor wearing many hats — not just count requests per key.

## When to use it

Reach for Metering in front of any resource where requests are expensive or abusable:

<CardGroup cols={2}>
  <Card title="LLM endpoints" icon="brain">
    Chat completions, support-bot turns, and any token-metered route where a runaway loop or coordinated abuse drains your model spend.
  </Card>
  <Card title="Expensive public routes" icon="server">
    A costly search, an export, or any unauthenticated endpoint where distributed abuse slips under a plain per-IP limit.
  </Card>
</CardGroup>

## How it works

<Steps>
  <Step title="Wrap the endpoint">
    Call `POST /v1/meter` from in front of the resource you want to protect — a chat completion, a support-bot turn, an expensive search, any public route. Pass an identifier for the caller (user id, session, IP) and the limit you want to enforce.
  </Step>

  <Step title="FormShield scores the request">
    We correlate the caller across IPs, sessions, and accounts to detect one actor wearing many hats, not just count requests per key. You get back an `allow` / `throttle` / `block` decision plus the abuse signals behind it.
  </Step>

  <Step title="Cap cost before it runs away">
    Set a budget per identity or per window and FormShield enforces it at the decision boundary, so a runaway loop or a coordinated abuse campaign hits the cap instead of your invoice.
  </Step>
</Steps>

## Quickstart

Call `POST https://api.formshield.dev/v1/meter` with your API key, the resource you're protecting, an identity for the caller, and the limit to enforce. FormShield scores the request and returns the decision in the standard [response envelope](/api-reference/introduction#response-envelope).

```bash
curl https://api.formshield.dev/v1/meter \
  -H "Authorization: Bearer $FORMSHIELD_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "resource": "chat.completion",
    "identity": { "user_id": "u_4821", "ip": "203.0.113.42" },
    "limit": { "max": 100, "window": "1h" }
  }'
```

Response:

```json
{
  "version": "1",
  "data": {
    "action": "throttle",
    "verdict": "multi_account_abuse",
    "confidence": 0.91,
    "usage": { "count": 138, "limit": 100, "window": "1h" },
    "linked_identities": 6
  },
  "error": null,
  "metadata": { "request_id": "req_9f2c1a", "processing_time_ms": 22 }
}
```

Here the same actor has been linked across six identities and is past the limit, so FormShield returns `throttle` — your code decides whether to serve, slow down, or reject.

## Request body

<ParamField body="resource" type="string" required>
  A label for the route you're protecting, e.g. `chat.completion`. Limits and usage are tracked per resource.
</ParamField>

<ParamField body="identity" type="object" required>
  An identifier for the caller. Pass any of `user_id`, `session`, or `ip` — the more you supply, the better FormShield correlates one actor across IPs, sessions, and accounts.
</ParamField>

<ParamField body="limit" type="object" required>
  The ceiling to enforce: `max` requests per `window` (e.g. `1h`). Use this for a per-window cap, or set a credit budget to cap cost on LLM routes.
</ParamField>

## Response

<ResponseField name="action" type="string">
  The decision: `allow`, `throttle`, or `block`. A clear action so you decide whether to serve, slow down, or reject — no opaque 429 with no reason attached.
</ResponseField>

<ResponseField name="verdict" type="string">
  The reason behind the action, e.g. `multi_account_abuse`. Names the abuse signal so the decision is never a black box.
</ResponseField>

<ResponseField name="confidence" type="float">
  How sure FormShield is of the verdict, from `0.0` to `1.0`.
</ResponseField>

<ResponseField name="usage" type="object">
  Current `count` against the `limit` for the `window`, so you can surface remaining headroom to the caller.
</ResponseField>

<ResponseField name="linked_identities" type="integer">
  How many identities FormShield correlated to this caller — the count that turns one actor cycling fresh accounts or rotating IPs into a single subject.
</ResponseField>

## Key signals

<CardGroup cols={2}>
  <Card title="Multi-account abuse correlation" icon="users">
    Links requests that share fingerprint, network, and behavioral signals so the same actor cycling fresh accounts or rotating IPs counts as one — the failure mode plain per-IP limits miss.
  </Card>
  <Card title="Cost caps for LLM endpoints" icon="brain">
    Enforce a credit or budget ceiling per identity and per window. The biggest win is a hard lid on token spend for chat and support bots before a single abuser drains it.
  </Card>
  <Card title="Allow / throttle / block decisions" icon="check">
    Every call returns a clear action plus a verdict and confidence, so you decide whether to serve, slow down, or reject.
  </Card>
  <Card title="Distributed enforcement at the edge" icon="globe">
    Runs on the same edge path as the rest of FormShield, so the limit check adds little latency and works the same whether traffic hits one region or many.
  </Card>
</CardGroup>

## Common questions

**How do I rate limit an AI endpoint by real abuse instead of raw IP counts?**

Coming soon: call `POST /v1/meter` in front of your LLM route with a caller identity and a limit. FormShield correlates the caller across IPs, sessions, and accounts and returns `allow` / `throttle` / `block`, so distributed abuse against a single endpoint is caught even when each IP looks under the limit. Join the early-access waitlist to try it on your endpoints.

**When is Metering available and how do I get early access?**

Metering is not live yet — it's in development behind the `POST /v1/meter` endpoint. It's the next FormShield surface after our live IP, email, content, and Voight products. Join the waitlist from the [dashboard](https://formshield.dev/app) to get early access and help shape the limit and budget model.

**How is Metering billed?**

At launch, Metering will cost 2 credits per decision — each `POST /v1/meter` call that returns an `allow` / `throttle` / `block` verdict. Credits are the same shared balance used across FormShield, billed per service rather than per raw request, so you can mix Metering with your other checks on one plan.

## Next steps

<CardGroup cols={2}>
  <Card title="API reference" icon="code" href="/api-reference/introduction">
    The standard response envelope, authentication, and error responses.
  </Card>
  <Card title="IP intelligence" icon="globe" href="/products/ip-intelligence">
    A live FormShield product today — score any IP's reputation by the credit.
  </Card>
</CardGroup>
