BlogCompose

I stopped walking into demo calls blind: every lead now comes with a usage brief written 10 seconds before the call

Founder-led sales has one structural weakness: you have no time to prep. If the lead has touched your product, their usage history is the best discovery call you'll never have to run - here's how I turn it into a one-page brief, automatically, before every call.

The code

Founder-led sales has one structural advantage over a sales team - you actually understand the product - and one structural weakness: you have no time to prep. So you join the demo call, ask "so, tell me about your use case," and spend the first ten minutes extracting information that's already sitting in your product analytics. If the lead has touched your product (trial, free tier, sandbox), their usage history is the best discovery call you'll never have to run. My app meters usage with Vevee (@vevee/sdk). Its compose() method generates structured JSON from a user's real usage and events - and nothing says the output has to be shown to the user. This one's for me:

import { createClient } from "@vevee/sdk";

const vevee = createClient({ apiKey: process.env.VEVEE_SECRET_KEY! });

interface SalesBrief {
  oneLiner: string;          // who this user appears to be
  usageSummary: string;      // what they did, in numbers
  topFeatures: string[];
  buyingSignals: string[];   // limit hits, pricing page visits, growth in usage
  risks: string[];           // stalled activation, single-feature dependence
  openingQuestion: string;   // first question to ask on the call
}

const brief = await vevee.compose<SalesBrief>(
  "pre-call-brief",
  leadUserId,
  { callType: "demo", plan: "trial" }
);

if (brief.status === "generated") {
  await postToSlack("#sales", formatBrief(brief.output));
}

What lands in Slack

The compose type is configured once in the dashboard. Intent prompt: "You are prepping a founder for a sales call with this user. Summarize their actual usage, infer their use case from behavior (not guesses), flag buying signals and risks, and propose ONE opening question that proves we did our homework." Data sources: user usage, user events, user attributes, conversion signals. Output schema: the interface above - it comes back as typed JSON, ready for Slack formatting. Wire it to your calendar webhook (Cal.com, Calendly, a tiny route handler) and the brief lands in Slack when the meeting is booked, again 15 minutes before it starts. Here is what one looks like:

  • Maria - solo dev, building what looks like a real-estate listing tool.
  • 7 active days in a 14-day trial. 142 generations, 90% of them image_generation with style: "staging". Hit the trial cap on day 9 and kept trying for two days - 31 blocked requests.
  • Buying signals: cap hit + persistence; usage doubled week-over-week; viewed pricing 3x.
  • Risks: never touched the API - everything through the UI. If the demo pitches API integration, it'll miss.
  • Opening question: "You've been staging a lot of listing photos - are you doing this for your own listings or for clients?"

Why this beats CRM enrichment tools

That brief took zero minutes of my time and answers the three questions that decide a sales call: what do they do, what wall did they hit, what should I not pitch. The 31 blocked requests after the cap is the kind of detail that's gold on a call and invisible in a CRM. Enrichment tools tell you the lead's company size and tech stack - facts about who they are. Usage data tells you what they did in your product this week, which is the only thing that predicts whether they'll buy it. You already have this data; it's just trapped in tables nobody reads before a call. compose() is the reading. Founder-led sales doesn't scale because prep doesn't scale. This is prep that scales - provided you run it with the right operational guardrails:

  • Server-side (sk_* key), triggered by webhook or cron - never in any client.
  • Costs fractions of a cent per brief (usage.costMicroUsd on every result); the dashboard's monthly compose budget caps the total.
If the lead opted out of AI personalization, the call returns opted_out and you prep the old way - the consent gate applies even when the audience is internal, which is exactly how it should work.
See your own numbers in two minutes.Add the SDK and your users, costs and revenue fill in on the next request.
Join waitlist

Keep reading

ShareCopy a link to this post.

Set your first limit in about five minutes.

50k operations free every month. No card required.
Join waitlist