
Rate Limiting and API Security Basics
Understand rate limiting, HTTPS, CORS, input validation, and essential API security concepts. Learn to build and consume APIs safely.
Rate Limiting and API Security Basics
Knowing how to make API calls is not enough — you also need to understand the security mechanisms that protect APIs. Rate limiting prevents abuse, HTTPS encrypts data, and input validation stops attacks. This lesson covers the security concepts every API developer must know.
1. Rate Limiting
Rate limiting controls how many requests a client can make in a given time window.
Why Rate Limiting Exists
| Without Rate Limiting | With Rate Limiting |
|---|---|
| One user can overload the server | Fair usage for all users |
| Bots can scrape all data | Automated abuse prevented |
| No usage tracking | Billing and quotas enforced |
| DDoS attacks succeed easily | Attack surface reduced |
How Rate Limits Work
graph TD
A[Client Request] --> B{Rate Limit Check}
B -->|Under limit| C[Process Request<br/>200 OK]
B -->|Over limit| D[Reject Request<br/>429 Too Many Requests]
C --> E[Decrement remaining count]
D --> F[Return Retry-After header]
style C fill:#059669,color:#fff
style D fill:#dc2626,color:#fff
Reading Rate Limit Headers
curl -I https://api.github.com/users/octocat
Response headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 55
X-RateLimit-Reset: 1708643600
X-RateLimit-Used: 5
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Max requests per window |
X-RateLimit-Remaining | Requests left in this window |
X-RateLimit-Reset | Unix timestamp when the window resets |
X-RateLimit-Used | Requests made in this window |
Common Rate Limits
| API | Free Tier Limit |
|---|---|
| GitHub | 60/hour (unauth), 5000/hour (auth) |
| 900/15 min (read), 300/15 min (write) | |
| Stripe | 100/sec |
| OpenAI | Varies by model and tier |
| Google Maps | 50/sec |
Handling Rate Limits in Code
#!/bin/bash
# Check rate limit before making request
REMAINING=$(curl -sI https://api.github.com/users/octocat | grep -i "x-ratelimit-remaining" | awk '{print $2}' | tr -d '\r')
if [ "$REMAINING" -gt 0 ]; then
echo "Requests remaining: $REMAINING"
curl -s https://api.github.com/users/octocat | jq '.name'
else
RESET=$(curl -sI https://api.github.com/rate_limit | grep -i "x-ratelimit-reset" | awk '{print $2}' | tr -d '\r')
echo "Rate limited. Resets at: $(date -r $RESET)"
fi
Exponential Backoff
When rate limited, wait progressively longer between retries:
Attempt 1: Wait 1 second
Attempt 2: Wait 2 seconds
Attempt 3: Wait 4 seconds
Attempt 4: Wait 8 seconds
Attempt 5: Wait 16 seconds
This prevents hammering the server and gives it time to recover.
2. HTTPS: Encrypting API Traffic
HTTP vs HTTPS
| HTTP | HTTPS |
|---|---|
| Port 80 | Port 443 |
| No encryption | TLS encryption |
| Data visible to anyone on the network | Data encrypted in transit |
| Anyone can modify data in transit | Tampering detected |
| No identity verification | Server identity verified via certificate |
What HTTPS Protects
graph LR
subgraph "HTTP (Insecure)"
A[Client] -->|Plain text| B[Attacker can read]
B --> C[Server]
end
subgraph "HTTPS (Secure)"
D[Client] -->|Encrypted| E[Attacker sees gibberish]
E --> F[Server]
end
style B fill:#dc2626,color:#fff
style E fill:#059669,color:#fff
Rule: NEVER send authentication credentials, tokens, or sensitive data over plain HTTP. Always use HTTPS.
3. CORS (Cross-Origin Resource Sharing)
CORS prevents unauthorized websites from making API calls on behalf of your users.
The Problem CORS Solves
Without CORS, a malicious website could:
- User visits
evil-site.comwhile logged intobank.com evil-site.commakes API calls tobank.com/apiusing the user's cookies- The bank's API processes the request thinking it is legitimate
CORS prevents this by requiring the API to explicitly allow cross-origin requests.
CORS for API Consumers
If you get a CORS error in the browser:
Access to fetch at 'https://api.example.com/data' from origin 'http://localhost:3000'
has been blocked by CORS policy
This is a server-side configuration issue, not a client bug. The API server needs to add CORS headers.
Important: CORS only affects browsers. cURL and Postman never encounter CORS errors.
4. Input Validation
APIs must validate all input to prevent attacks:
SQL Injection
Dangerous input:
{"username": "admin'; DROP TABLE users; --"}
APIs prevent this by using parameterized queries, never by concatenating user input into SQL strings.
Cross-Site Scripting (XSS)
Dangerous input:
{"comment": "<script>steal(document.cookie)</script>"}
APIs prevent this by sanitizing HTML and encoding output.
What You Should Do as an API Consumer
- Send clean data — do not include special characters unnecessarily
- Validate on your side too — do not rely solely on the API
- Handle error responses — if the API rejects your input, read the error details
5. API Security Checklist
| Security Practice | For API Consumers | For API Builders |
|---|---|---|
| Use HTTPS | Always | Always |
| Store credentials securely | Env variables, not code | Hashed in database |
| Handle rate limits | Check headers, implement backoff | Return 429 with Retry-After |
| Validate input | Send clean, typed data | Validate all input |
| Use minimal permissions | Request only needed scopes | Principle of least privilege |
| Keep tokens secret | Never log or expose tokens | Short expiration times |
| Monitor for abuse | Watch for 429s and 403s | Log and alert on suspicious activity |
Summary and Key Takeaways
- Rate limiting protects APIs from abuse — check headers and implement backoff.
- HTTPS encrypts all data in transit — never send credentials over HTTP.
- CORS prevents unauthorized websites from calling APIs — it only affects browsers.
- Input validation prevents SQL injection and XSS attacks.
- Store credentials in environment variables, never in source code.
- Use exponential backoff when rate limited.
Lesson Review Quiz
?Knowledge Check
What does X-RateLimit-Remaining: 0 in a response header mean?
?Knowledge Check
Why does CORS not affect cURL or Postman?
?Knowledge Check
What is exponential backoff?