Browse docs

Database schema

SQLite (libSQL) schema defined in db/schema.ts. Apply with drizzle-kit push.

users

Internal user id, unique clerk_user_id, optional email, created_at.

workspaces

name, plan (free | pro), Stripe fields (stripe_customer_id, stripe_subscription_id, subscription_status, current_period_end), created_at.

workspace_members

Composite PK (workspace_id, user_id), role (default owner), created_at. Cascade delete when workspace or user is removed.

links

  • id (uuid), slug (unique), destination_url
  • bot_title, bot_description, optional og_image_url
  • created_at, optional workspace_id (null = legacy anonymous links still resolvable)
  • Optional: campaign, notes, utm_source, utm_medium, utm_campaign
  • expires_at, is_active (boolean, default true)

link_clicks

id, link_id → links, slug, created_at, optional referrer, country. Indexed on (link_id, created_at).

api_keys

id, workspace_id, key_hash (SHA-256 of raw key), optional name, created_at, last_used_at.

custom_domains

id, workspace_id, unique host, verified boolean, created_at.

stripe_events_processed

event_id (PK), created_at — idempotent webhook processing.

rate_limit_buckets

id, key (fingerprint string), window_start, count — per-minute buckets for create-link rate limiting.