You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The SDK automatically handles API rate limits. When the API returns HTTP 429 (Too Many Requests), the client will:
43
+
The SDK uses a two-layer approach to keep your requests within API limits:
44
+
45
+
| Layer | Type | How it works |
46
+
|---|---|---|
47
+
|**Native Throttling**| Proactive (client-side) | Sliding window rate limiter blocks outgoing requests *before* they hit the server |
48
+
|**429 Retry & Adaptive Polling**| Reactive (server-side) | Catches HTTP 429 responses, retries with backoff, and slows polling when limits are low |
49
+
50
+
The proactive layer prevents most 429 errors from ever occurring. The reactive layer acts as a safety net for edge cases (clock drift, concurrent processes, plan changes).
51
+
52
+
---
53
+
54
+
## Native Throttling
55
+
56
+
Every `SharpApiClient` instance includes an in-memory **sliding window rate limiter** (`SlidingWindowRateLimiter`) that tracks request timestamps in a 60-second rolling window.
57
+
58
+
Before each API call, `waitIfNeeded()` checks the window. If capacity is available the request proceeds immediately; if not, the call sleeps until the oldest timestamp expires out of the window.
59
+
60
+
-**Default limit:** 60 requests/minute (matches most subscription plans)
61
+
-**Per-process, in-memory** — no external dependencies (Redis, database, etc.)
62
+
-**Server-adaptive** — when the server returns a higher `X-RateLimit-Limit` header (e.g. after a plan upgrade), the limiter automatically ratchets up to match. It never ratchets *down*, so your configured default is always the floor.
63
+
-**Metadata bypass** — `ping()` and `quota()` skip throttling to avoid deadlocks when checking connectivity or subscription status.
64
+
65
+
### Configuration
66
+
67
+
```php
68
+
$client = new SharpApiClient('your-api-key');
69
+
70
+
// Change the throttle limit (default: 60)
71
+
$client->setRequestsPerMinute(120);
72
+
73
+
// Disable throttling entirely (pass 0)
74
+
$client->setRequestsPerMinute(0);
75
+
```
76
+
77
+
### Advanced Throttling Controls
78
+
79
+
You can access the underlying `SlidingWindowRateLimiter` instance directly for fine-grained control:
80
+
81
+
```php
82
+
$limiter = $client->getRateLimiter();
83
+
84
+
// Non-blocking check — returns true if a request can proceed without waiting
85
+
$limiter->canProceed();
86
+
87
+
// How many requests are available in the current window
88
+
$limiter->remaining(); // e.g. 42
89
+
```
90
+
91
+
**Cross-process state caching** — save and restore the server-reported rate limit state (e.g. between HTTP requests in a web app):
92
+
93
+
```php
94
+
// After an API call, cache the server-reported state
**Quick quota check** — verify the server still reports available capacity before making a request:
104
+
105
+
```php
106
+
if ($client->canMakeRequest()) {
107
+
// Server-reported remaining > 0 (or no server data yet)
108
+
}
109
+
```
110
+
111
+
---
112
+
113
+
## Automatic 429 Retry & Adaptive Polling
114
+
115
+
If a request does hit the server rate limit, the SDK handles it automatically:
44
116
45
117
1.**Retry automatically** — reads the `Retry-After` header, sleeps for the specified duration, and retries the request (up to 3 times by default).
46
118
2.**Slow down polling** — during `fetchResults()`, when `X-RateLimit-Remaining` drops below the low threshold, polling intervals are automatically increased to avoid hitting the limit.
0 commit comments