Rate limits
WatchLLM returns Promptwatch-style rate-limit headers on authenticated REST requests, MCP metadata responses, and successful MCP tool calls.
X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset
Local development uses persisted Postgres quota storage, not an in-process counter. Organization quota rows live in api_usage, and the per-IP guard stores SHA-256 IP hashes in api_ip_usage.
Quota model
Authenticated REST and MCP calls share the same organization hourly quota. Project-scoped keys resolve the organization through their project. Organization-scoped keys use X-Project-Id for REST project routes or projectId in MCP tool arguments when a tool needs project context, but the quota still belongs to the organization.
- Explore: 100 requests per hour
- Solo: 500 requests per hour
- Startup: 2,000 requests per hour
- Business: 10,000 requests per hour
- Enterprise: 50,000 requests per hour
The reset value is the next UTC hour as a Unix epoch in seconds.
IP guard
The local API layer also applies a durable per-IP guard of 1,000 requests per minute. IP addresses are never stored raw; WatchLLM stores only the SHA-256 hash plus the minute window.
Error shape
Project-context errors return JSON with error and message fields.
{
"error": "MISSING_PROJECT_ID",
"message": "X-Project-Id header required for this endpoint."
}MCP initialize, tools/list, and successful tools/call responses consume the shared organization quota and include the same three X-RateLimit-* headers. Invalid bearer requests and organization-scoped tool calls missing project context return before consuming organization quota.
When the organization hourly quota is exceeded, REST returns 429 with rate-limit headers and Retry-After.
{
"error": "Too Many Requests",
"message": "You've hit your hourly API request limit of 100 requests. Please retry after the quota resets.",
"retryAfter": 3600,
"limit": 100,
"remaining": 0
}When the per-IP guard is exceeded, REST returns 429 with the Promptwatch-style guard body.
{
"code": "RATE_LIMITED",
"message": "Too many requests, please slow down",
"statusCode": 429
}Local verification
The committed smoke:rest-core script verifies consecutive authenticated /api/v2/validate calls return X-RateLimit-Remaining values that decrement. smoke:mcp verifies authenticated MCP initialize, tools/list, and tools/call responses carry the same quota headers while unauthorized and missing-project calls do not consume organization quota. The rate-limit task queue also covers the persisted per-IP and per-organization 429 paths.