# Rate Limits

Source: https://developer.eagleview.com/documentation/general/rate-limits

## Overview

Eagleview APIs have per-second limits to keep performance consistent and the platform stable.

This page shows the default limits, what happens if you exceed them, and how to build clients that stay within the limits.

## Default limits

Each Eagleview API has a default rate limit, measured in requests per second. Some APIs have multiple rate limit plans, and some customers may have higher limits based on their plan or a special agreement.

The following table lists the default limits for each Eagleview API:

|  |  |  |  |
| --- | --- | --- | --- |
| **API** | **Endpoint** | **Default rate limit (requests per second)** | **Extendable?** |
| [Authentication](https://developer.eagleview.com/docs/authentication/overview.md) | [Generate Token](https://developer.eagleview.com/docs/authentication/api-documentation.md#operation/POST%20/oauth2/v1/token) | 4 | No |
| [Imagery](https://developer.eagleview.com/docs/imagery/overview.md) | [Discovery](https://developer.eagleview.com/docs/imagery/api-documentation.md#tag/Discovery) | 5 | Yes |
| [Imagery](https://developer.eagleview.com/docs/imagery/overview.md) | [Tiles](https://developer.eagleview.com/docs/imagery/api-documentation.md#tag/Tiles) | 300 | Yes |
| [Imagery](https://developer.eagleview.com/docs/imagery/overview.md) | [Images](https://developer.eagleview.com/docs/imagery/api-documentation.md#tag/Images) | 5 | Yes |
| [WMTS](https://developer.eagleview.com/documentation/wmts/v1/overview) | [GetCapabilities](https://developer.eagleview.com/documentation/wmts/v1/api-documentation#tag/GetCapabilities) | 5 | Yes |
| [WMTS](https://developer.eagleview.com/documentation/wmts/v1/overview) | [GetTile](https://developer.eagleview.com/documentation/wmts/v1/api-documentation#tag/GetTile) | 500 | Yes |
| [Property Data](https://developer.eagleview.com/docs/property-data/overview.md) | All | 30 | No |
| [Measurement Orders](https://developer.eagleview.com/docs/measurement-orders/overview.md) | All | 10 | No |
| [TrueDesign](https://developer.eagleview.com/docs/truedesign/overview.md) | All | 30 | No |

If you go over a limit, the API returns a `429 Too many Requests` response:

```
{
  "status": 429,
  "error": "too_many_requests",
  "message": "Rate limit exceeded. Please retry later."
}
```

![Diagram showing how a rate limiter controls API traffic. “Your Application” sends multiple API requests. The rate limiter passes allowed requests through to the “Web Service” but blocks excess requests, returning a 429 Too Many Requests error.](http://d2o59litegue4w.cloudfront.net/inline-images/Rate%20Limiting%20diagram.png)

## Designing for limits

To keep your integration running smoothly, make sure it spreads requests out and handles `429` errors without retrying too aggressively.

These patterns are language-agnostic and can be applied in any client:

- **Retry with pauses**. If you get a `429` or other temporary error, wait before trying again. Increase the wait time after each failure, but stop after a reasonable limit.
- **Spread out requests**. For big jobs (like fetching many tiles), use a small pool of workers and send requests at a steady pace instead of in bursts.
- **Cache tokens**. Always store and reuse access tokens until they expire. Don’t cache other API data unless your contract explicitly allows it.
- **Send fewer requests.** If the API allows it, combine data into larger requests instead of sending many small ones.
- **Refresh smartly**. Handle token generation on a timer or refresh early, so you don’t hit the 4 rps authentication limit.

### Requesting higher limits

If you often run into limits on an extendable API, please [submit a support request](support/requests/). Be ready to share:

- Which API(s) you use
- Your typical and peak request volumes
- Why you need the extra capacity

## Advanced usage patterns (optional)

These strategies are meant for high-volume use cases, like downloading thousands of tiles or managing tokens across many services. Most integrations won’t need this level of detail, but if you’re running at scale, they can help keep things smooth.

### Example: Scheduling a tile-heavy job under WMTS GetTile (500 rps)

If you need to download tens of thousands of tiles, the 500 requests-per-second ceiling becomes important. The wrong approach could trigger `429` errors and slow your job. A better approach is to send requests at a steady pace, retry with longer waits after errors, and keep concurrency at a manageable level.

Here’s how you could design a working solution:

- **Rate limiter**: stay just below the 500 rps ceiling to leave headroom.
- **Concurrency**: use a modest worker pool pulling from a central queue, tuned to your environment.
- **Retry policy**: add a backoff with jitter for `429` or `5xx` errors, capped at a maximum delay.
- **Idempotency**: tile requests are deterministic URLs, so it is safe to retry them.
- **Throughput math**: a simple planning rule is `job time ≈ total tiles ÷ allowed rps`, plus any retry delays.

The following minimal Python example shows how to throttle tile requests, retry with backoff on errors, and keep concurrency under control:

```
import time, random, requests
from concurrent.futures import ThreadPoolExecutor

ALLOWED_RPS = 490  # slightly under 500
WORKERS = 200

def fetch_tile(url, session, retries=5):
    for attempt in range(1, retries + 1):
        resp = session.get(url, timeout=10)
        if resp.status_code == 200:
            return True
        if resp.status_code == 429 or 500 <= resp.status_code < 600:
            delay = min(30, random.uniform(2**(attempt-1), 2**attempt))
            time.sleep(delay)
            continue
        return False
    return False

def run_job(tile_urls):
    session = requests.Session()
    with ThreadPoolExecutor(max_workers=WORKERS) as pool:
        list(pool.map(lambda u: fetch_tile(u, session), tile_urls))
```

### Example: Refreshing tokens safely under the 4 rps auth limit

The authentication endpoint allows four token requests per second for each set of client credentials. If multiple apps or services share the same credentials and refresh on their own, you can quickly exceed that shared limit.

A better approach is to centralize token refresh, renew proactively before tokens expire, and make sure only one refresh happens at a time.

Here’s how you could design a working solution:

- **Central manager**: one component fetches and shares tokens; others just read from it.
- **Single-flight refresh**: only one refresh runs at a time, guarded by a mutex or lock.
- **Proactive renewal**: refresh around 80–85% of the TTL with a bit of jitter to spread out load.
- **Grace window**: treat tokens as expiring about 60 seconds early to account for clock drift.
- **Backoff**: retry on `429` or `5xx` errors with capped exponential backoff.

This pattern assumes several workers or processes share one set of client credentials. If each service has its own credentials, manage refresh within that service instead.

Here’s a minimal Python example of a token manager that caches tokens, refreshes them early, and ensures only one refresh happens at a time:

```
import threading, time, requests

class TokenManager:
    def __init__(self):
        self.token = None
        self.expiry = 0
        self.lock = threading.Lock()

    def get_token(self):
        with self.lock:
            now = time.time()
            # Use cached token if still valid (with 60s safety window)
            if self.token and self.expiry - now > 60:
                return self.token
            # Otherwise refresh
            resp = requests.post("https://…/token", data={"client_id": "…"})
            data = resp.json()
            self.token = data["access_token"]
            self.expiry = now + data.get("expires_in", 3600)
            return self.token
```

This example shows the core idea: cache the token, refresh it early, and use a lock so only one refresh runs at a time. For production, you could also add proactive scheduling, jitter, and backoff for error handling.

## Wrapping up

Most Eagleview integrations won’t hit rate limits as long as you pace your requests and avoid sending more than you need at once. If you need extra capacity, [reach out to support](support/requests/) about extendable APIs.

For large-scale jobs, the advanced patterns in the previous section show how you can stay within the limits without slowing down. Keeping these practices in mind will help your integration stay fast, reliable, and production-ready.
