Frontend Keys
When using a frontend (client) API key, you can configure per-IP rate limit rules and per-IP stream limits to control how each individual IP address can use your application. This helps prevent abuse from any single user.
Per-IP Rate Limit Rules
Per-IP limit rules let you define granular rate limits that apply to each IP address using your frontend key. Each rule specifies:
- Scope: What requests the rule applies to (per upstream, specific upstream, etc.)
- Limit Unit: How the limit is measured (compute units, request count)
- Window: The time window for the limit (e.g. 5 minutes)
- Limit: The maximum allowed in the time window (use 0 to block)
Rules are evaluated independently - a request must satisfy all applicable rules to be allowed.
Scope Types
Default per upstream
Creates a separate rate limit counter for each upstream service type. This means an IP gets the specified limit for each service they use.
Scope: Default per upstream
Limit: 50,000 Compute Units
Window: 5 minutesWith this rule, a single IP could use:
- 50,000 CUs against the node API
- 50,000 CUs against the indexer API
- etc.
In other words, each upstream maintains its own counter.
Specific upstream
Applies a limit only to a specific upstream service (e.g., node API, indexer API). Other upstreams are unaffected by this rule. You can use this to grant a higher limit to particular upstream, or alternatively you could set the value to zero to block a particular upstream.
In most cases you should use this in conjunction with a “default per upstream” rule. You can find the node operation IDs by looking for operationId in the OpenAPI spec.
Default per node operation
Similar to “Default per upstream” but for node API operations. Each operation (like get_account, get_transactions) gets its own counter.
Specific node operation
Set a different limit for a specific node API operation.
Default per GraphQL table
Creates separate counters for each GraphQL table accessed through GraphQL APIs. These include the core indexer API as well as no code indexing APIs. See all GraphQL tables (e.g. account_transactions) for the core indexer API here.
Specific GraphQL table
Set a different limit for a specific GraphQL table.
Default vs specific scopes
Understanding the difference between “Default per X” and “Specific X” scopes is important for setting up effective rate limits.
Default scopes (like “Default per Upstream”) create a separate counter for each item in that category. If you set a limit of 50,000 CUs with “Default per Upstream”, each upstream type gets its own 50,000 CU allowance.
Specific scopes (like “Upstream: NodeApi”) apply only to that one item. You can combine a default scope with specific overrides:
Rule 1: Default per Upstream - 50,000 CUs / 5min
Rule 2: Upstream: NodeApi - 20,000 CUs / 5minIn this case:
- Node API is limited to 20,000 CUs (the specific rule overrides the default)
- All other upstreams get 50,000 CUs each
Example configurations
Simple protection
One rule giving each upstream its own limit:
| Scope | Limit | Unit | Window |
|---|---|---|---|
| Default per Upstream | 100,000 | Compute Units | 5 min |
Service-Specific Limits
Different limits for different services. Note: you should always include a default rule.
| Scope | Limit | Unit | Window |
|---|---|---|---|
| Default per Upstream | 50,000 | Compute Units | 5 min |
| Upstream: NodeApi | 100,000 | Compute Units | 5 min |
| Upstream: IndexerApi | 30,000 | Compute Units | 5 min |
Protect expensive tables
Limit specific expensive GraphQL tables:
| Scope | Limit | Unit | Window |
|---|---|---|---|
| Default per Upstream | 100,000 | Compute Units | 5 min |
| Default per GraphQL Table | 50,000 | Compute Units | 5 min |
| GraphQL table: token_activities | 5,000 | Compute Units | 5 min |
This allows generous overall usage but restricts the expensive token_activities table.
Block all traffic except for specific tables
To express “block all upstreams except for specific indexer API tables”, you need multiple rules that work together:
| Scope | Limit | Unit | Window |
|---|---|---|---|
| Default per Upstream | 0 | Request Count | 5 min |
| Upstream: IndexerApi | 1,000,000 | Request Count | 5 min |
| Default per GraphQL Table | 0 | Request Count | 5 min |
| GraphQL table: coin_activities | 100 | Request Count | 5 min |
| GraphQL table: token_activities | 100 | Request Count | 5 min |
How this works:
- Default per Upstream = 0: Blocks all upstreams by default.
- Upstream: IndexerApi = high value: Allows the indexer API (overrides the default).
- Default per GraphQL Table = 0: Blocks all GraphQL tables by default.
- Specific GraphQL tables = intended limit: Allows only the tables you specify with their intended rate limits.
This pattern lets you create allowlist-style rules where everything is blocked except what you explicitly permit.
Note: This kind of overriding behavior only works for rules with the same “key”, where key is unit (e.g. request count) + window (e.g. 5 mins).
Per-IP Concurrent Stream Limit
In addition to rate limits, you can configure a per-IP concurrent stream limit. This controls how many long-running streaming connections (such as WebSocket or gRPC streams) each IP address can have open simultaneously.
Why use stream limits?
Streaming connections are long-lived and consume server resources for their entire duration. Without limits, a single malicious or misbehaving client could:
- Open hundreds of connections from one IP, exhausting your organization’s stream quota
- Prevent legitimate users from establishing new connections
- Cause unexpected costs
How it works
When you set a per-IP stream limit (e.g., 2), each IP address using your frontend key can only have that many concurrent streams open at once. If they try to open more, the connection will be rejected with an HTTP 429 (Too Many Requests) error. Setting the limit to 0 will block all streaming connections for frontend keys.
The per-IP stream limit works alongside your organization’s overall stream limit. Both limits are checked - a connection must satisfy both to be allowed.
Example
If you set:
- Per-IP stream limit: 2
- Organization stream limit: 100
Then:
- Each individual IP can have at most 2 concurrent streams
- Your organization can have up to 100 total streams across all IPs
- If one IP opens 2 streams, they cannot open more until one closes
- Other IPs are unaffected and can still open their own streams (up to 2 each)