All API routes are located in app/api/ and follow Next.js 16 App Router conventions.
Description: Subscribe a user to the newsletter mailing list.
POST /api/newsletter
Content-Type: application/json
{
"email": "user@example.com"
}Success (200):
{
"message": "Successfully subscribed to newsletter"
}Error (400): Invalid email
{
"error": "Invalid email address"
}Error (409): Already subscribed
{
"error": "Email already subscribed"
}Error (429): Rate limit exceeded
{
"error": "Too many requests. Please try again later."
}Error (500): Server error
{
"error": "Failed to subscribe"
}- Limit: 5 requests per 15 minutes per IP
- Window: Sliding window
- Header:
X-RateLimit-Remaining
const subscribeToNewsletter = async (email: string) => {
try {
const response = await fetch('/api/newsletter', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email }),
})
if (!response.ok) {
const error = await response.json()
throw new Error(error.error)
}
const data = await response.json()
return data
} catch (error) {
console.error('Newsletter subscription failed:', error)
throw error
}
}Description: Search eBay products using the consolidated eBay API.
GET /api/ebay/search?q=iphone&category=electronics&limit=20| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q |
string | Yes | - | Search query |
category |
string | No | - | Product category filter |
limit |
number | No | 20 | Results per page (max 100) |
offset |
number | No | 0 | Pagination offset |
sort |
string | No | BestMatch |
Sort order |
condition |
string | No | - | New, Used, or Refurbished |
Success (200):
{
"items": [
{
"id": "123456789",
"title": "iPhone 15 Pro Max",
"price": 1199.99,
"currency": "USD",
"image": "https://i.ebayimg.com/...",
"url": "https://ebay.com/itm/...",
"condition": "New",
"shipping": "Free",
"location": "United States"
}
],
"total": 1250,
"hasMore": true
}Error (400): Missing or invalid parameters
{
"error": "Search query is required"
}Error (429): Rate limit exceeded
{
"error": "eBay API rate limit exceeded"
}Error (500): Server error
{
"error": "Failed to search products"
}Currently, the API does not require authentication for public endpoints.
Future: When user accounts are added, we'll use:
- JWT tokens for session management
- OAuth 2.0 for third-party auth
- API keys for programmatic access
| Endpoint | Limit | Window | Status |
|---|---|---|---|
/api/newsletter |
5 requests | 15 minutes | ✅ Active |
/api/ebay/* |
100 requests | 1 hour | ✅ Active |
/api/* (default) |
1000 requests | 1 hour | ✅ Active |
X-RateLimit-Limit: 5
X-RateLimit-Remaining: 4
X-RateLimit-Reset: 1640995200
All errors follow this structure:
interface ErrorResponse {
error: string // Human-readable error message
code?: string // Machine-readable error code
details?: any // Additional error context
timestamp?: string // ISO 8601 timestamp
}| Code | Meaning | Usage |
|---|---|---|
200 |
OK | Successful request |
201 |
Created | Resource created |
400 |
Bad Request | Invalid input |
401 |
Unauthorized | Authentication required |
403 |
Forbidden | No permission |
404 |
Not Found | Resource not found |
409 |
Conflict | Resource already exists |
429 |
Too Many Requests | Rate limit exceeded |
500 |
Internal Server Error | Server error |
503 |
Service Unavailable | Temporary outage |
- All inputs are validated before processing
- Email addresses checked with regex
- SQL injection prevention (parameterized queries)
- XSS prevention (sanitized outputs)
// Allowed origins
const allowedOrigins = [
'https://ebay-store.vercel.app',
'http://localhost:3000' // Development only
]X-Content-Type-Options: nosniffX-Frame-Options: SAMEORIGINX-XSS-Protection: 1; mode=block
Currently: v1 (implicit)
Future: API versioning will be added:
/api/v1/newsletter/api/v2/newsletter
All API requests are logged with:
- Timestamp
- Method and path
- IP address
- User agent
- Response status
- Response time
Tracked via Vercel Analytics:
- Request count
- Error rate
- Response time (p50, p95, p99)
- Rate limit hits
Last Updated: February 16, 2026
API Version: 1.0
Status: Production Ready ✅