We enabled public API testing for your quickstart demo while maintaining strong security.
Only these specific endpoints are public (no auth required):
/api/v1/calculate/electricity/api/v1/calculate/flight/api/v1/calculate/fuel/api/v1/calculate/spend
Everything else still requires authentication. Your company data, user management, admin routes, and billing are all still protected.
Per IP Address:
- 100 requests per hour
- Tracked in-memory (fast performance)
- Automatic reset after 1 hour
- Clear error messages with retry information
Example response when rate limited:
{
"success": false,
"error": "Rate limit exceeded for public testing",
"message": "Sign up for a free API key at https://zerocarbon.codes/signup",
"resetAt": "2026-02-07T15:30:00Z"
}- Public endpoints: Allow
*(necessary for demos) - All other endpoints: Strict origin validation
- Preflight requests handled properly
- Credentials only for authenticated requests
Public testing requests:
- β Calculate emissions (read-only operations)
- β Cannot write to database
- β Cannot access company data
- β Cannot see other users' data
- β Cannot modify anything
Each endpoint supports two modes:
Mode 1: Authenticated (with API key)
curl -H "Authorization: Bearer your_api_key" ...
# Benefits:
# - Higher rate limits (120 req/min)
# - Usage tracking
# - Custom configurations
# - Support accessMode 2: Public Testing (no API key)
curl ... # No auth header
# Limitations:
# - 100 req/hour only
# - No usage tracking
# - Standard configurations only
# - Auto error responsesAll inputs are validated:
- Type checking (number, string, enum)
- Range validation (min/max values)
- Format validation (country codes, fuel types)
- SQL injection protection
- XSS prevention
All responses include:
X-RateLimit-Limit: 100X-RateLimit-Remaining: 87X-RateLimit-Reset: 1707318600X-Content-Type-Options: nosniffX-Frame-Options: DENYStrict-Transport-Security(production)
Prevention: Rate limiting at 100/hour per IP. Even with 1000 IPs, that's only 100,000 requests/hour, which your infrastructure can easily handle.
Prevention: Public endpoints don't return any sensitive data. They only calculate emissions using hardcoded emission factors. No database queries for user data.
Prevention:
- All inputs validated before processing
- TypeScript type safety
- Prisma ORM (parameterized queries)
- No raw SQL in public endpoints
Prevention:
- Rate limiting per IP
- Cloudflare protection (if using)
- Lightweight calculations (no heavy DB queries)
- Can add additional WAF rules if needed
Prevention: Public endpoints don't use API keys. Authenticated endpoints have separate rate limiting (3 requests per IP per endpoint per minute for failed auth attempts).
Prevention: Middleware checks path explicitly. Only whitelisted endpoints bypass auth. Everything else requires valid JWT or API key.
- Emission Factors - These are public knowledge anyway (IPCC, EPA, govt standards)
- Calculation Formulas - Standard industry calculations
- Country/Fuel/Flight Data - Static reference data
- β User accounts or emails
- β Company information
- β API keys
- β Usage statistics
- β Billing data
- β Custom emission factors
- β Historical data
- β Admin access
- β Database structure
- β Internal configurations
| Attack Scenario | Likelihood | Impact | Mitigation |
|---|---|---|---|
| High-volume requests | Medium | Low | Rate limiting, 100/hr cap |
| Malicious input | Low | None | Input validation, type safety |
| Data theft | None | None | No sensitive data in public endpoints |
| Account compromise | None | None | Auth still required for all sensitive routes |
| Cost inflation | Low | Low | Rate limiting prevents abuse |
| Reputation damage | Low | Low | Professional error messages, monitoring |
Overall Risk Level: LOW β
- Public endpoint usage (requests/hour)
- Rate limit hits (how many IPs hitting the limit)
- Error rates (validation errors, 500s)
- Geographic distribution (unusual countries?)
- Conversion rate (public test β signup)
- π¨ >10,000 public requests in 1 hour (possible abuse)
β οΈ >10% error rate (possible attack or bug)- π >500 unique IPs in 1 hour (viral or suspicious)
// Add to your monitoring service
if (publicRequestsLastHour > 10000) {
alert('Unusual public API activity');
}
if (uniqueIPsLastHour > 500) {
alert('Potential viral traffic or DDoS');
}-
Add Cloudflare WAF
Rate limiting: 100 req/hour per IP (done) Bot protection: Challenge suspected bots Geographic blocking: Block specific countries if needed -
Add Request Signing
// Require a timestamp + hash for public requests const signature = hmac(timestamp + body, public_salt);
-
Add CAPTCHA for High Volume
if (requestsLastMinute > 10) { require('captcha-verification'); }
-
Add Honeypot Endpoints
// Fake endpoints that log suspicious actors /api/v1/admin/users // Trap endpoint
Before going to production:
- Rate limiting implemented (100/hr per IP)
- Only specific endpoints are public
- Input validation on all public endpoints
- No sensitive data returned
- CORS configured correctly
- Security headers added
- Error messages don't leak information
- Monitoring set up (recommended)
- Alerts configured (recommended)
- Cloudflare or WAF enabled (optional)
// Add to middleware (already done in code):
if (rateLimit.count > 100) {
// Block for 24 hours
blockedIPs.set(ip, Date.now() + 86400000);
}// Log and block immediately
if (body.match(/DROP|DELETE|INSERT|UPDATE/i)) {
logSecurityEvent('SQL Injection Attempt', { ip, body });
return 403;
}// If someone tries authenticated endpoints without keys
if (failedAuthAttempts > 10) {
blockIP(ip, '1 hour');
}Your API is now:
- β Accessible for demos (100 free requests/hour)
- β Secure against common attacks
- β Scalable (rate limiting prevents abuse)
- β Monetizable (easy upgrade path to paid plans)
- β Professional (proper error handling and headers)
No security vulnerabilities introduced. All sensitive endpoints remain protected. Only calculation endpoints (which use public data) are accessible for testing.
Public testing endpoints != security risk
We're only exposing calculations using public emission factors. No user data, no company data, no admin access. Combined with strict rate limiting and validation, this is a safe, professional implementation that will help with your YC application while keeping your platform secure.
Questions or concerns? Review the code:
- Middleware:
middleware.ts(lines 1-100) - Rate limiting logic:
middleware.ts(lines 20-50) - Public endpoint handling: Each route file in
src/app/api/v1/calculate/