Use Case

A customer database built for SaaS

You built a SaaS product. You have users in a database. But do you have a single place where you can look up any customer, see their plan, their last activity, and whether they're also using another product you built — without opening Postgres, a spreadsheet, and three browser tabs at the same time? TinyCRM is that place.

The problem

SaaS founders track customers in spreadsheets, Notion databases, or not at all. The spreadsheet starts as a temporary measure — just a list of beta users — and then quietly becomes load-bearing infrastructure. Months later it's being manually updated by whoever remembers to update it, filled with duplicates, and missing everyone who signed up in the last three weeks.

The deeper problem is that spreadsheets are manual. They don't know when someone upgrades from free to paid. They don't know when someone churns, or when a user who signed up under one email starts using a different one. Every entry requires a human to notice the event and update a row. At any meaningful scale, that is impossible to sustain.

The alternative — building a proper CRM — feels disproportionate. Setting up HubSpot, Salesforce, or Attio for a solo-founder SaaS takes more time than the product itself. They're built for sales teams, not for founders who need a filterable customer list and an API to keep it current.

How TinyCRM solves it

TinyCRM is a structured database with email as the merge key and an NPM SDK to keep it automatically up to date. You install the SDK once, call identify() in your sign-up flow, and every new customer appears in a filterable dashboard without any manual work.

1

Install the SDK and call identify() on sign-up

One npm install, one API key, one identify() call in your sign-up handler. Every new customer appears automatically. No manual entry, no cron jobs, no integrations to maintain.

2

Pass any custom data via JSONB params

The identify() call accepts a params object with any key-value pairs. Pass plan tier, MRR, billing cycle, referral source, or anything that matters for your product. This data is stored, indexed, and filterable in the dashboard.

3

Update status when customers upgrade or churn

Call identify() again whenever a customer's status changes. Updating to status: 'paid' after a Stripe webhook fires keeps your customer database accurate without any manual intervention.

4

Import historical data via CSV

Already have customers in a spreadsheet? Upload a CSV and map your columns to TinyCRM fields. Historical data merges with SDK-tracked data into the same unified table.

What you get

Automatic tracking

The NPM SDK sends customer data to TinyCRM from your backend on every sign-up, upgrade, or status change. No manual entry, no cron jobs, no Zapier chains. The database stays current because your app updates it directly.

Structured data with JSONB params

Every customer-project relationship stores structured custom data in a JSONB params field. Plan tier, MRR, billing cycle, referral source — anything relevant to your product. The data is indexed and filterable, not locked in free-text notes.

Filterable customer table

The dashboard is a filterable table, not a card-based CRM UI. Filter by project, status, param key-value, or date range. Find all paid customers on the pro plan in under three clicks. Export any filtered view as CSV.

CSV import and export

Import historical customers from any spreadsheet using the built-in CSV importer with column mapping. Export any filtered view whenever you need the data elsewhere. You own your data and can always get it out.

Tracking a customer with custom params

Pass any structured data you care about in the params field. All of it will be stored, indexed, and filterable in the TinyCRM dashboard.

import { TinyCRM } from "tinycrm-sdk";

const crm = new TinyCRM({
  apiKey: process.env.TINYCRM_API_KEY,
});

// On sign-up: track the customer as a free user
await crm.identify({
  email: user.email,
  name: user.name,
  status: "free",
  params: {
    plan: "starter",
    source: "product_hunt",
    signed_up_at: new Date().toISOString(),
  },
});

// After a successful Stripe payment: update to paid
await crm.identify({
  email: user.email,
  status: "paid",
  params: {
    plan: "pro",
    mrr: 29,
    stripe_customer_id: stripeCustomer.id,
  },
});

Frequently asked questions

Can I import my existing customer data into TinyCRM?

Yes. TinyCRM has a built-in CSV importer with a column matcher. Export your spreadsheet or Airtable base as a CSV, upload it to TinyCRM, and map columns to the email, name, status, and params fields. Historical data lands in the same unified table as SDK-tracked customers.

What kind of custom data can I store per customer?

Each customer-project relationship has a JSONB params field that accepts any key-value data. Store plan tier, MRR, billing cycle, referral source, company name, role, or any other field that matters to your product. The dashboard lets you filter by any param key-value pair.

Does TinyCRM replace my application database?

No. TinyCRM sits alongside your application database, not instead of it. Your Postgres or MySQL schema stays exactly as it is. TinyCRM is where you read the unified view — your app database is where you write the source of truth.

Can I export my TinyCRM data?

Yes. TinyCRM supports CSV export with the same filters available in the dashboard. Export all customers, or filter by project, status, or date range before exporting. You own your data and can take it with you at any time.

Replace your spreadsheet today

14-day free trial. $9/month after. Import from CSV in minutes.

Also see: TinyCRM vs spreadsheets · TinyCRM vs Airtable · All use cases · Spreadsheet to CRM migration guide