Public API
Third-party integrations and developer platform
Overview
Current state
Internal oRPC API only, no external access.
Target state
- Public REST API with OpenAPI spec
- API keys and rate limiting
- Developer portal with docs
- Webhooks for events
Use cases
- Price comparison sites
- Inventory management tools
- Analytics integrations
- Automated listing tools
API design
Authentication
Authorization: Bearer <api_key>API keys are scoped:
read:items- Read public listingswrite:items- Create/update own listingsread:orders- Read own orderswebhooks- Receive webhook events
Endpoints
GET /v1/items # List items (public)
GET /v1/items/:id # Get item details
POST /v1/items # Create listing (auth)
PATCH /v1/items/:id # Update listing (auth)
DELETE /v1/items/:id # Delete listing (auth)
GET /v1/categories # List categories
GET /v1/brands # List brands
GET /v1/me # Current user info
GET /v1/me/items # My listings
GET /v1/me/orders # My orders
POST /v1/webhooks # Register webhook
GET /v1/webhooks # List webhooks
DELETE /v1/webhooks/:id # Remove webhookRate Limits
| Tier | Requests/min | Requests/day |
|---|---|---|
| Free | 60 | 1,000 |
| Basic | 300 | 10,000 |
| Pro | 1,000 | 100,000 |
Architecture
API key management
export const apiKeys = pgTable('api_keys', {
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('user_id').references(() => users.id),
name: varchar('name', { length: 100 }),
key: varchar('key', { length: 64 }).unique(), // hashed
prefix: varchar('prefix', { length: 8 }), // visible part: "cute_xxxx"
scopes: jsonb('scopes').$type<string[]>(),
tier: varchar('tier', { length: 20 }).default('free'),
lastUsedAt: timestamp('last_used_at'),
expiresAt: timestamp('expires_at'),
createdAt: timestamp('created_at').defaultNow(),
});Rate limiting
import { Ratelimit } from '@upstash/ratelimit';
import { Redis } from '@upstash/redis';
const ratelimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(60, '1 m'),
analytics: true,
});
async function checkRateLimit(apiKey: string) {
const { success, limit, remaining, reset } = await ratelimit.limit(apiKey);
if (!success) {
throw new APIError(429, 'Rate limit exceeded', {
'X-RateLimit-Limit': limit,
'X-RateLimit-Remaining': remaining,
'X-RateLimit-Reset': reset,
});
}
}Webhooks
export const webhooks = pgTable('webhooks', {
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('user_id').references(() => users.id),
url: varchar('url', { length: 500 }),
events: jsonb('events').$type<string[]>(),
secret: varchar('secret', { length: 64 }),
isActive: boolean('is_active').default(true),
createdAt: timestamp('created_at').defaultNow(),
});
// Webhook events
type WebhookEvent =
| 'item.created'
| 'item.updated'
| 'item.sold'
| 'order.created'
| 'order.completed'
| 'message.received';
// Send webhook
async function sendWebhook(userId: string, event: WebhookEvent, data: any) {
const hooks = await db.query.webhooks.findMany({
where: and(
eq(webhooks.userId, userId),
eq(webhooks.isActive, true),
),
});
for (const hook of hooks) {
if (!hook.events.includes(event)) continue;
const signature = createHmac('sha256', hook.secret)
.update(JSON.stringify(data))
.digest('hex');
await fetch(hook.url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Cute-Signature': signature,
'X-Cute-Event': event,
},
body: JSON.stringify({ event, data, timestamp: Date.now() }),
});
}
}Implementation
Core API
Build API key generation, basic endpoints (items, categories), rate limiting, and OpenAPI spec.
Authentication
Add scoped permissions, key management UI, and usage analytics.
Webhooks
Implement webhook registration, event delivery, retry logic, and delivery logs.
Developer portal
Create API documentation site, interactive API explorer, SDKs (JS, Python), and example integrations.
Checklist
Infrastructure
- API keys table
- Rate limiting with Redis
- Request logging
- Error handling
Endpoints
- Items CRUD
- Categories and brands
- User info
- Orders (authenticated)
Webhooks
- Webhook registration
- Event dispatching
- Signature verification
- Retry mechanism
Developer portal
- Documentation site
- API key management UI
- Usage dashboard
- OpenAPI spec export