Rate Limiting

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.

Endpoint Limit Window Purpose
Login 5 requests 15 minutes Credential stuffing protection
TOTP verification 5 requests 15 minutes TOTP brute force protection
Token refresh 20 requests 15 minutes Normal app operation (more lenient)
Registration 3 requests 1 hour Mass account creation prevention
Password reset 3 requests 1 hour Email flooding prevention
Email verification resend 3 requests 1 hour Email 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.

Header Description
X-RateLimit-Limit Maximum requests allowed in the current window
X-RateLimit-Remaining Requests remaining in the current window
X-RateLimit-Reset Unix 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.