Polar revenue analytics for SvelteKit
This guide adds ProductLense to a SvelteKit site and connects Polar, so every Polar payment is attributed to the channel, campaign and landing page that first brought the customer. It takes four steps and about ten minutes.
1. Add ProductLense to SvelteKit
The script goes in src/app.html. Replace SITE_ID with the id from Settings → Sites.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script>window.productlense=window.productlense||function(){(window.productlense.q=window.productlense.q||[]).push(arguments)}</script>
<script defer data-site="SITE_ID" src="https://api.productlense.app/a.js"></script>
%sveltekit.head%
</head>
<body>
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>2. Identify signed-in users
<script lang="ts">
let { data, children } = $props();
$effect(() => {
if (data.user) window.productlense?.('identify', data.user.id, { email: data.user.email });
});
</script>
{@render children()}3. Connect Polar
Setup steps
- In Polar, open Settings → Developers and create an organization access token with the four read scopes.
- In ProductLense, open Settings → Billing connections → Polar and paste the token and organization id.
- In Polar → Settings → Webhooks, add a webhook endpoint with the URL ProductLense shows after you save the connection (pattern https://api.productlense.app/api/webhooks/{provider}/{connection_id}).
- Select the events listed below and paste the generated secret into ProductLense.
- ProductLense backfills 12 months of orders.
Credentials and permissions
| Field | Secret | Where to find it |
|---|---|---|
| Organization access token | Yes, encrypted at rest | Settings → Developers → New token with customers:read, subscriptions:read, orders:read and organizations:read. |
| Organization ID | No | The UUID shown in Settings → General. |
| Webhook secret | Yes, encrypted at rest | The secret generated when you add the webhook endpoint pointing at ProductLense. |
Webhook
URL pattern, shown with your connection id after you save:
https://api.productlense.app/api/webhooks/polar/{connection_id}Events: order.created, order.paid, order.updated, order.refunded, subscription.created, subscription.updated, subscription.active, customer.created, customer.updated, customer.state_changed
Verification: Standard Webhooks signature headers.
What ProductLense reads
- Customers
- Customers with email and external id.
- Subscriptions
- Subscriptions with status and interval.
- Payments
- Orders.
- Refunds
- The refunded amount on each order, plus refunded tax.
- Fees
- The platform fee amount when present on the order, otherwise 0.
What ProductLense never touches
- Never creates, changes, refunds or cancels anything: read-only API calls and incoming webhooks only.
- Never moves money, issues payouts, or reads bank account details.
- Never sees full card numbers; providers do not expose them.
- Never sends your customer data to the AI model: Ask and the daily insight see aggregates only.
Match payments to your users
Set the Polar customer external id to the id you pass to identify.
await fetch('https://api.polar.sh/v1/checkouts/', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.POLAR_ACCESS_TOKEN}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ products: [PRODUCT_ID], external_customer_id: user.id }),
});Polar on SvelteKit: questions
- Where does the ProductLense script go in SvelteKit?
- In src/app.html. Paste the queue stub and script tag into the <head> of src/app.html, before %sveltekit.head%. The script is about 2.3 KB, loads with defer, sets no cookies, and records route changes in single-page apps through the history API, so no extra router code is needed.
- How do I identify users in SvelteKit?
- Call window.productlense('identify', userId) once the signed-in user is known, as in the src/routes/+layout.svelte example on this page. Use the same id you store on Polar as pl_user_id, so Polar payments match by id rather than by email.
- Does ProductLense work with Polar?
- Yes. ProductLense connects to Polar with organization access token, organization ID, webhook secret, backfills 12 months of history, and stays current through signed webhooks plus a nightly reconcile. One connection is included on Starter; Growth and Scale allow every provider at once on the same site.
- What data does ProductLense read from Polar?
- Customers, subscriptions, payments, refunds and fees, read-only. Payments: orders. Refunds: the refunded amount on each order, plus refunded tax. Fees: the platform fee amount when present on the order, otherwise 0.
- Can ProductLense change anything in my Polar account?
- No. ProductLense only makes read calls and receives webhooks. It never creates, changes, refunds or cancels anything, never moves money, and never sees card numbers. Credentials are encrypted at rest, and the AI features only ever see aggregated numbers, never your customers’ data.
Free up to 10k events a month. No card.
Add the script, connect Stripe or any of 14 other billing providers, and see revenue by channel the same day.