The SpeyBooks API applies rate limits per IP address to protect the platform and ensure fair usage across all accounts. Limits vary by endpoint sensitivity.

Default limit

Most API endpoints allow 100 requests per minute per IP address. This applies to all authenticated resource endpoints (invoices, contacts, transactions, accounts, quotes, reports, and so on) unless a stricter limit is specified below.

Authentication endpoints

Auth endpoints use tighter limits to protect against credential stuffing, brute force, and email flooding. These override the default limit.

EndpointLimitWindowPurpose
Login5 requests15 minutesCredential stuffing protection
TOTP verification5 requests15 minutesTOTP brute force protection
Token refresh20 requests15 minutesNormal app operation (more lenient)
Registration3 requests1 hourMass account creation prevention
Password reset3 requests1 hourEmail flooding prevention
Email verification resend3 requests1 hourEmail flooding prevention

All auth rate limits are keyed by IP address. The account lockout mechanism (5 failed login attempts, 15-minute lockout) operates independently of rate limiting and is tracked per account rather than per IP.

Response headers

Every response includes rate limit headers so your client can track usage proactively.

HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the window resets

Exceeding the limit

When you exceed the rate limit, the API returns a 429 Too Many Requests response with a Retry-After header indicating how many seconds to wait before retrying.

Handling rate limits

Your client should check the Retry-After header and wait the specified duration before retrying. If the header is not present, use exponential backoff starting at 1 second with a maximum delay of 30 seconds.

For batch operations, avoid sending requests in tight loops. Space requests evenly across the window or use perPage=100 on list endpoints to reduce the total number of calls needed.

Best practices

Respect X-RateLimit-Remaining and slow down before hitting zero rather than waiting for a 429. Cache responses where appropriate, particularly for data that changes infrequently like chart of accounts or organisation details. If your integration needs to process large volumes, use pagination efficiently and consider queuing requests with controlled concurrency.