Skip to content
DocsQuickstart

Get started

Quickstart: from sign-up to your first attributed customer

Create a workspace, connect billing and search, install the snippet and call identify(). What appears the same day, and what needs new customers first.

This page takes you from a new account to the first customer Joinsight can credit to a page. Most of it takes one sitting. The part you can't speed up is waiting for new customers to arrive after the snippet is live, so the page also says what you can read on day one and what fills in over the following weeks.

You'll need:

  • A Stripe account you can create a restricted key in, or a RevenueCat project you can create an API v2 secret key in. Either one is enough.
  • A Google account with access to your Search Console property. If you use GA4 or Plausible, access to that too.
  • Access to your site's HTML, your signup code and the code that creates Stripe Checkout sessions. This is only needed for attribution, which is optional.

Create your account and a workspace

Sign in with your email. Joinsight sends a link and a 6-digit code; there is no password. If "Continue with Google" is offered, that works too, and both reach the same account because accounts are keyed by email. Signing in for the first time creates the account.

Then create a workspace. A workspace is one product: its billing, its search property and its site. The form asks for three things:

FieldWhat it does
Workspace nameUsually your product's name.
Reporting currencyEUR, USD, GBP, CHF, CAD or AUD. Every amount is converted to it with daily ECB reference rates.
Time zonePrefilled from your browser. The Monday brief arrives at 08:00 in this time zone.

You can change all three later in Settings. The time zone has to be an IANA name, such as Europe/Paris.

Creating the workspace shows its secret key once, with a copy button. Your server only needs it if you call identify() from your backend; Joinsight keeps a hash, so copy it now or rotate a new one later in Settings → Keys. Continue to setup then opens the Setup page.

The setup checklist

Setup lists five steps. Each one shows its state: done, waiting (connected and importing), optional, or skipped. The page counts them as "N of 5 steps done" and refreshes on its own while a step is waiting.

StepRequiredWhat it unlocks
1. Connect a revenue sourceYesMRR, movements, customers, one-time sales and their history
2. Add mobile: RevenueCat and App Store ConnectNo, skip it if you only sell on the webMobile MRR and trials, store page views and downloads by source
3. Connect Search ConsoleYesClicks, impressions and positions by page and query. The step is done once a Search Console property syncs; GA4 or Plausible is optional and adds sessions by landing page
4. Install the snippetNo, you can skip itThe first touch of each visitor: the basis of page, channel and keyword revenue
5. Link payments to signupsNo, you can skip itEach new customer credited to the page and channel that first brought them

Until your workspace has revenue, the Overview screen shows the same steps, minus the mobile one, under "Get your first answer", with the step to do next highlighted. Once billing has imported a payment, or once every step is done or skipped, the Overview becomes the dashboard.

Step 1: connect billing

Joinsight reads billing data and never writes to it.

Stripe. Paste a restricted key; secret keys and publishable keys are refused. The Stripe card has a link that opens Stripe's key form with the right Read permissions already ticked, so check them and create the key. Keys starting with rk_live_ connect your live data and keys starting with rk_test_ connect test mode. The list includes Charges, which covers sales outside subscriptions, such as Checkout in payment mode and Payment Links. A key without it still connects, but those one-time sales are left out until you add it.

RevenueCat. Paste an API v2 secret key and your project ID, then add the webhook URL and Authorization header shown on the card to RevenueCat's webhook settings, so renewals and cancellations arrive as they happen.

The backfill starts right away and its progress shows on the card. Every subscription is imported, not only the ones created after you connected, so the MRR chart covers your whole history. The exact permissions, sync frequency and how a subscription visible in both Stripe and RevenueCat is counted once are on Connect Stripe and RevenueCat.

Connecting Stripe or RevenueCat starts your 14-day trial clock. Signing up and creating a workspace don't. See The trial below.

Step 2: add mobile sources

Skip this if you only sell on the web. If you sell in an app, connect RevenueCat (if you didn't in step 1) and App Store Connect. App Store data arrives 1–2 days after connecting. Details are on Connect App Store Connect and Instagram.

Step 3: connect Search Console and traffic

Sign in with Google, then pick your Search Console property and select Save and sync. Until a property is saved, the Google card shows Setup not finished and nothing imports. In the same form, choose a traffic source: GA4 (then pick the property), Plausible, or None. Plausible connects separately, with a Stats API key on its own card, and only one of the two can be the traffic source. With None, the snippet still counts visitors per page.

Search Console keeps 16 months of performance data, and Joinsight imports all of it on the day you connect. That is why keyword and page click data is useful before the snippet has recorded anything. GA4 is backfilled 13 months and Plausible 12 months. Search Console data runs 2–3 days behind, which is Google's delay, not a sync problem. More on Connect Search Console, GA4 or Plausible.

Step 4: install the snippet

The snippet is a small first-party script, under 2 KB. It records where each visitor first landed: the landing page, the referring domain, UTM tags and ad click IDs. Copy the exact tag from the Setup page, because it carries your workspace's public site key:

<script>window.joinsight=window.joinsight||function(){(joinsight.q=joinsight.q||[]).push(arguments)}</script>
<script defer src="…/j.js" data-site="js_site_…"></script>

The snippet stores nothing until it has consent. Call this from your cookie banner:

joinsight("consent", true);  // accepted
joinsight("consent", false); // refused or withdrawn

If consent is handled elsewhere, or doesn't apply to you, add data-consent="granted" to the script tag instead.

After deploying, open your site in a new private window by typing its address, and accept your banner on that first page. Only a landing page starts a session: a page reached through a link on your own site doesn't. The "Last session" check on the Setup page turns green on the first event. Serving the script from your own domain, so ad blockers don't drop it, is covered on Install the tracking snippet.

This step is what turns a visit into a credited customer. It takes two small changes.

Call identify() once, right after signup succeeds, with your own user ID and the email:

joinsight("identify", user.id, user.email);

This links the visitor's anonymous ID to your user ID. The email is hashed on arrival and only used as a fallback match. You can also identify from your server with the workspace's secret key; see Link visitors to customers with identify().

Put the same user ID on the Stripe subscription. Stripe doesn't copy Checkout Session metadata to the subscription or customer, so set it with subscription_data.metadata:

// Stripe Checkout: tag the customer and subscription with your user ID
const session = await stripe.checkout.sessions.create({
  mode: "subscription",
  line_items: [{ price: priceId, quantity: 1 }],
  client_reference_id: user.id,
  customer_email: user.email,
  subscription_data: { metadata: { user_id: user.id } },
  success_url: "https://yourapp.com/welcome",
});
// For existing customers: stripe.customers.update(id, { metadata: { user_id: user.id } })

Joinsight reads metadata.user_id from the Stripe customer, and from the subscription when the customer has none. For RevenueCat, use the same user ID as the app user ID; anonymous RevenueCat IDs are ignored. When no user ID matches, Joinsight falls back to the hashed email, which only works if the person paid with the email they signed up with. The reasons for each placement are in Stripe Checkout metadata and the user ID.

Then check it end to end. Sign up on your site as a new visitor, then pay. How depends on what is connected, and the Setup step says which applies:

  • A test-mode Stripe key: pay with a test card.
  • A live Stripe key: test payments never reach it, so subscribe with a real card on your cheapest plan. You can refund it in Stripe afterwards, but cancel at the end of the period rather than immediately, so it still counts as paid. Your next real customer who signs up after the snippet went live works just as well.
  • RevenueCat only: sandbox purchases are left out, so subscribe for real with the account you just created.

The Setup step first shows "identify() works" with the number of signups it has seen, then "Ready" once a paying customer links to their first visit. Linking runs about two minutes after an identify() call and again after billing syncs, so give it a few minutes.

What appears when

Joinsight is useful on day one, but attribution is only as good as the number of customers who arrived after the snippet went live.

WhenWhat you see
Minutes after connecting billingCombined MRR and its full history, net new MRR and the movements behind it, active subscribers, trial conversion, churn, one-time sales, at-risk MRR on past-due subscriptions
The day you connect Google16 months of Search Console clicks, impressions and positions by page and query, plus GA4 or Plausible traffic
1–2 days after connecting App Store ConnectStore impressions, product page views and downloads by source
From the first consented visitSessions by landing page and channel
From the first customer who visits, signs up and pays after the snippet and identify() are liveThat customer's first page and channel, and the first attributed MRR
About 30 days after the snippet goes livePage, channel and keyword revenue reliable enough to act on, and keyword opportunities, which rank queries on pages that already earn

While the snippet is younger than 30 days, the Overview shows "Attribution warming up: day N of 30" with a progress bar. Customers who signed up before the snippet and identify() were live have no first touch and stay unattributed; that history isn't recoverable. How the numbers are built is on How attribution works.

Skipping the optional steps

Attribution is opt-in. If you only want combined MRR and search data, skip the snippet and linking steps with "Skip" on the Setup page or the Overview checklist. A skipped step is remembered for everyone in the workspace, and "Undo" brings it back. Skipping the snippet also skips linking, because linking needs the snippet.

Once the steps are done or skipped, the Overview shows the dashboard even before a payment arrives. Its page panel then says attribution is off, with a link back to Setup, and the trial emails don't ask you to install what you skipped.

The trial

The trial gives you 14 days with every feature and no card required.

  • The clock starts when your first revenue source connects, not at sign-up. Exploring the sample workspace doesn't start it.
  • Day 2 to 4: if the snippet hasn't sent an event, or identify() hasn't been called yet, you get one email with the exact missing step and an offer to set it up together on a short call. Skipped steps don't trigger it.
  • Day 12: an email with what Joinsight found so far: new paying customers, how many were attributed, and your top page if one has earned.
  • Day 14: if fewer than 5 new paying customers were matched to a first touch during the trial, the trial is extended once by another 14 days, and you get an email saying so. Fewer matches than that is too few to judge which pages make money, and the 30-day attribution warm-up is longer than the trial anyway.

The days left show at the bottom of the sidebar, with a link to choose a plan. Plans are on pricing, and billing is covered in Workspaces, team, settings and billing.

Explore with sample data

While your own workspace is still empty, the Overview offers "Create a sample workspace", and the workspace switcher offers it at any time when you don't have one. It builds a separate workspace for a fictional app with 16 months of revenue, search, App Store and Instagram data. It takes about 20 seconds and leaves your workspace untouched.

The sample workspace is marked "sample data" in the workspace switcher, doesn't count toward your plan's workspace limit, and doesn't sync: its connections are read-only. It's a quick way to see what each screen looks like with months of history before your own attribution has warmed up.

Next steps