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 Header
Authorization: Bearer <api_key>

API keys are scoped:

  • read:items - Read public listings
  • write:items - Create/update own listings
  • read:orders - Read own orders
  • webhooks - Receive webhook events

Endpoints

API 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 webhook

Rate Limits

TierRequests/minRequests/day
Free601,000
Basic30010,000
Pro1,000100,000

Architecture

API key management

packages/db/schema/api-keys.ts
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

packages/api/rate-limit.ts
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

packages/db/schema/webhooks.ts
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