Quick Start
Get up and running with CreateaSaaS in under five minutes. No complex configuration required.
- 1Create a project in the dashboard. Sign in to your CreateaSaaS account and create a new project. You will receive a publishable key (
mh_pk_...) that identifies your project. - 2Add the script tag to your site. Paste the snippet into your HTML
<head>tag. It starts tracking automatically -- no extra code needed. - 3See analytics data flowing in. Open your project dashboard. Within seconds you will see page views, sessions, and visitor data appear in real time.
Script Tag
The simplest integration method. Add a single script tag to your site and CreateaSaaS automatically tracks page views, sessions, visitor IDs, and referrers.
<script
src="https://your-domain.com/sdk/dist/createasaas.js"
data-key="mh_pk_..."
data-project="your-project-id"
></script>What gets auto-tracked
- Page views -- every navigation is captured with URL, title, and timestamp.
- Sessions -- grouped by visitor with duration and page count.
- Visitor IDs -- anonymous, persistent identifiers for returning visitors.
- Referrers -- where your traffic comes from.
Replace your-domain.com with the domain where your CreateaSaaS platform is hosted. The data-key and data-project attributes are found on your project settings page.
Embeddable Widgets
Drop pre-built UI widgets into your site for support chat, announcements, and blog content. Each widget is self-contained and styled to blend with your design.
<script
src="https://your-domain.com/sdk/dist/createasaas-widgets.js"
data-key="mh_pk_..."
data-project="your-project-id"
data-widgets="support,announcements,blog"
></script>Configuration
The data-widgets attribute accepts a comma-separated list of widget names to load. Only the widgets you specify will be injected.
Available Widgets
| Widget | Description |
|---|---|
| support | Floating support chat widget. Users can submit tickets and view responses without leaving your site. |
| announcements | In-app notification bell with a dropdown showing your latest announcements and changelogs. |
| blog | Embeddable blog feed that renders your published posts directly within your application. |
React / Next.js
For React and Next.js applications, use the @createasaas/nextjs package for a first-class integration with hooks and context.
npm install @createasaas/nextjsProvider Setup
Wrap your application in the CreateaSaaSProvider at the top level. This initializes the SDK and provides context to all hooks.
import { CreateaSaaSProvider } from '@createasaas/nextjs';
export default function App({ Component, pageProps }) {
return (
<CreateaSaaSProvider publishableKey="mh_pk_...">
<Component {...pageProps} />
</CreateaSaaSProvider>
);
}Hooks Reference
| Hook | Returns | Description |
|---|---|---|
| useCreateaSaaS() | sdk | Access the full SDK instance. Use for custom event tracking, user identification, and direct API calls. |
| useAnalytics() | { track, identify, page } | Convenience hook for analytics. Call track(event, props) to send custom events. |
| useSupport() | { submit, tickets } | Submit support tickets and read ticket history programmatically from your React components. |
Server-to-Server API
For backend integrations, use your secret key to call the CreateaSaaS API directly from your server. Secret keys start with mh_sk_ and must never be exposed to the client.
Authentication
Include your secret key in the Authorization header as a Bearer token.
curl -X POST https://your-domain.com/api/sdk/v1/analytics/track \
-H "Authorization: Bearer mh_sk_..." \
-H "Content-Type: application/json" \
-d '{"event": "signup", "userId": "user_123"}'Submit a Support Ticket
const response = await fetch('https://your-domain.com/api/sdk/v1/support/submit', {
method: 'POST',
headers: {
'Authorization': 'Bearer mh_sk_...',
'Content-Type': 'application/json',
},
body: JSON.stringify({
subject: 'Cannot access billing page',
message: 'User reports a 403 error when visiting /billing.',
email: 'user@example.com',
priority: 'high',
}),
});
const ticket = await response.json();
console.log(ticket.id); // "tkt_abc123"Track an Event
await fetch('https://your-domain.com/api/sdk/v1/analytics/track', {
method: 'POST',
headers: {
'Authorization': 'Bearer mh_sk_...',
'Content-Type': 'application/json',
},
body: JSON.stringify({
event: 'purchase_completed',
userId: 'user_123',
properties: {
plan: 'pro',
amount: 29.00,
currency: 'USD',
},
}),
});Get Announcements
const response = await fetch('https://your-domain.com/api/sdk/v1/announcements', {
headers: {
'Authorization': 'Bearer mh_sk_...',
},
});
const { announcements } = await response.json();
// [{ id, title, content, publishedAt }, ...]Blog
Each project includes a built-in blog. Create and manage posts from the dashboard, then display them on your site via the public API or the blog widget.
Dashboard
Navigate to Manage → Blog in your project sidebar. You can create, edit, publish, and delete posts. Each post has a title, slug, content, excerpt, and SEO fields (meta title, meta description).
Fetching Posts (Public API)
const res = await fetch('https://your-domain.com/api/sdk/v1/blog/posts?page=1&limit=10', {
headers: { 'Authorization': 'Bearer mh_pk_...' },
});
const { posts, total } = await res.json();
// posts: [{ id, title, slug, excerpt, cover_image, author, tags, published_at }]Fetching a Single Post
const res = await fetch('https://your-domain.com/api/sdk/v1/blog/posts/my-post-slug', {
headers: { 'Authorization': 'Bearer mh_pk_...' },
});
const { post } = await res.json();
// post: { id, title, slug, content, excerpt, tags, published_at, ... }Blog Widget
Alternatively, use the blog widget to render posts without any custom code. Add blog to your data-widgets attribute, or place an inline mount:
<div data-createasaas-widget="blog"></div>Support Tickets
Let your users submit support tickets directly from your site. View and manage all tickets from the dashboard.
Dashboard
Navigate to Manage → Support to see all submitted tickets. You can filter by status (open, in progress, closed) and update ticket status. The sidebar badge shows the count of open tickets.
Submitting a Ticket (Public API)
const res = await fetch('https://your-domain.com/api/sdk/v1/support/submit', {
method: 'POST',
headers: {
'Authorization': 'Bearer mh_pk_...',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Jane Doe',
email: 'jane@example.com',
subject: 'Cannot access billing page',
message: 'I see a 403 error when visiting /billing.',
priority: 'Normal', // Normal, High, Low
}),
});
const { id } = await res.json();Support Widget
The support widget adds a floating chat button to your site. Users fill in their details and submit a ticket without leaving the page. Add support to your data-widgets attribute.
Announcements
Share product updates, new features, and bug fixes with your users. Manage announcements from the dashboard and display them via the widget or API.
Dashboard
Navigate to Manage → Announcements. Each announcement has a title, content, type (update, feature, bugfix, announcement), and a publish toggle. Only published announcements are visible to end users.
Types
| Type | Use Case |
|---|---|
| announcement | General announcements, company news |
| feature | New feature launches |
| bugfix | Bug fixes and patches |
| update | General product updates, improvements |
Fetching Announcements (Public API)
const res = await fetch('https://your-domain.com/api/sdk/v1/announcements?limit=20', {
headers: { 'Authorization': 'Bearer mh_pk_...' },
});
const { announcements, total } = await res.json();
// announcements: [{ id, title, content, type, published_at }]Announcements Widget
The announcements widget shows a bell icon with an unread badge. Clicking it opens a dropdown with your latest announcements. It tracks read state via localStorage so users only see the badge for new items. Add announcements to your data-widgets attribute.
User Management
CreateaSaaS tracks end users of your SaaS product. Users are created via the SDK auth endpoints or identified automatically through analytics events.
Dashboard
Navigate to Manage → Users to see all tracked users with search, pagination, and status filters. Click a user to view their profile, activity timeline, and session history.
End User Auth (SDK)
The SDK provides built-in auth endpoints so your users can sign up, sign in, and manage their sessions. Passwords are hashed server-side, and sessions are managed via JWT tokens.
// Sign up a new end user
const res = await fetch('https://your-domain.com/api/sdk/v1/auth/signup', {
method: 'POST',
headers: {
'Authorization': 'Bearer mh_pk_...',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: 'user@example.com',
password: 'securepassword',
name: 'Jane Doe',
}),
});
const { user, sessionToken } = await res.json();
// Sign in
const login = await fetch('https://your-domain.com/api/sdk/v1/auth/signin', {
method: 'POST',
headers: {
'Authorization': 'Bearer mh_pk_...',
'Content-Type': 'application/json',
},
body: JSON.stringify({ email: 'user@example.com', password: 'securepassword' }),
});
const { user: loggedIn, sessionToken: token } = await login.json();Get Current User
Pass the session token in the X-Session-Token header to fetch the authenticated user.
const res = await fetch('https://your-domain.com/api/sdk/v1/auth/me', {
headers: {
'Authorization': 'Bearer mh_pk_...',
'X-Session-Token': sessionToken,
},
});
const { user } = await res.json();Heatmaps & Recordings
Visualize exactly how users interact with your site through click heatmaps, scroll depth analysis, and full session recordings.
Dashboard
Navigate to Analytics → Heatmaps to view click heatmaps and scroll depth for any page. Use Analytics → Recordings to replay individual user sessions.
Tracking Heatmap Data
The SDK script tag automatically tracks clicks, mouse movements, and scroll depth. For custom tracking, use the heatmap API directly:
await fetch('https://your-domain.com/api/sdk/v1/heatmap/track', {
method: 'POST',
headers: {
'Authorization': 'Bearer mh_pk_...',
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'click', // click, movement, scroll, batch
data: {
session_id: 'sess_abc123',
visitor_id: 'v_def456',
page_path: '/pricing',
x: 450, y: 320,
x_percent: 35.2, y_percent: 44.4,
viewport_width: 1280, viewport_height: 720,
element_tag: 'BUTTON',
element_text: 'Get Started',
},
}),
});Session Recordings
Session recordings capture full DOM snapshots and incremental mutations using rrweb, allowing you to replay exactly what a user saw and did. The recording script is a separate, lightweight addition (~24KB gzipped) that runs alongside the main SDK.
Installation
Add the recording script tag after the main CreateaSaaS SDK tag. It uses the same data-key attribute for authentication.
<!-- Main SDK (analytics, events, etc.) -->
<script
src="https://your-domain.com/sdk/dist/createasaas.js"
data-key="mh_pk_..."
data-project="your-project-id"
></script>
<!-- Session Recording (add after main SDK) -->
<script
src="https://your-domain.com/sdk/createasaas-recording.js"
data-key="mh_pk_..."
data-api="https://your-domain.com"
></script>How It Works
When the recording script loads, it takes a full DOM snapshot of the page and then observes incremental mutations (attribute changes, text edits, node additions/removals, mouse movements, scroll positions, and input changes). Recording data is compressed and uploaded in chunks every 10 seconds to minimize network overhead. Recordings are automatically finalized when the user navigates away or closes the tab.
- 1Script loads and calls
POST /sdk/v1/recordings/startto create a new recording session on the server. - 2rrweb captures a full DOM snapshot followed by incremental mutations as the user interacts with the page.
- 3Every 10 seconds, accumulated events are sent via
POST /sdk/v1/recordings/chunkas a compressed chunk. - 4On page unload, the recording is finalized via
POST /sdk/v1/recordings/stopwith the final duration and event count.
Privacy Controls
Session recordings are designed with privacy in mind. All input fields are masked by default -- users will see placeholder dots instead of actual typed values in replays. You can further control what gets recorded using CSS classes on any element:
| CSS Class | Effect |
|---|---|
| csaas-no-record | Blocks recording of an element entirely. The element and all its children are excluded from the DOM snapshot and will not appear in replays. |
| csaas-ignore | Ignores an element during recording. The element is present in the DOM snapshot but mutations and interactions within it are not tracked. |
| csaas-mask | Masks the text content of an element. Text is replaced with asterisks in the recording so sensitive information is never captured. |
<!-- Block this entire section from recordings -->
<div class="csaas-no-record">
<p>This content will not appear in session replays.</p>
</div>
<!-- Mask sensitive text (e.g. account numbers) -->
<span class="csaas-mask">Account: 4242-XXXX-XXXX-1234</span>
<!-- Ignore interactions within this element -->
<div class="csaas-ignore">
<button>Clicks here are not tracked</button>
</div>Programmatic Control
If you need to start or stop recording manually instead of using the auto-start script tag, use the global CreateaSaaSRecording object:
// Initialize recording manually (if not using data-key auto-start)
CreateaSaaSRecording.init({
apiKey: 'mh_pk_...',
apiUrl: 'https://your-domain.com',
});
// Stop the current recording session
CreateaSaaSRecording.stop();
// Check if a recording is in progress
if (CreateaSaaSRecording.isRecording()) {
console.log('Recording is active');
}Limits
- Max duration -- recordings are capped at 10 minutes per session. A new recording starts automatically if the user continues browsing.
- Retention -- recording data is retained for 30 days and then automatically purged.
- Script size -- the recording script is approximately 24KB gzipped, loaded asynchronously so it does not block page rendering.
A/B Testing
Run experiments to optimize conversion rates. Create experiments in the dashboard, then use the API to assign visitors to variants and track conversions.
Dashboard
Navigate to Grow → A/B Tests to create experiments. Set the page path, variant names, and traffic weights. View results with conversion rates per variant.
Assign a Visitor to a Variant
const res = await fetch(
'https://your-domain.com/api/sdk/v1/ab/assign/EXPERIMENT_ID?visitor_id=v_abc123',
{ headers: { 'Authorization': 'Bearer mh_pk_...' } }
);
const { variant, variantName } = await res.json();
// variant: "a" or "b"
// variantName: "Blue Button" or "Green Button"
if (variant === 'b') {
// Show variant B
}Record a Conversion
await fetch('https://your-domain.com/api/sdk/v1/ab/convert/EXPERIMENT_ID', {
method: 'POST',
headers: {
'Authorization': 'Bearer mh_pk_...',
'Content-Type': 'application/json',
},
body: JSON.stringify({ visitor_id: 'v_abc123' }),
});Discount Codes
Create and manage discount codes for your product. Codes can be percentage-based or fixed-amount, with optional usage limits and expiration dates.
Dashboard
Navigate to Grow → Discounts to create codes. Set the code string, type (percentage or fixed), value, max uses, and expiration date.
Validating a Code (Public API)
Let your checkout flow validate codes in real time:
const res = await fetch('https://your-domain.com/api/sdk/v1/discounts/validate', {
method: 'POST',
headers: {
'Authorization': 'Bearer mh_pk_...',
'Content-Type': 'application/json',
},
body: JSON.stringify({ code: 'WELCOME20' }),
});
const { valid, type, value, error } = await res.json();
// valid: true, type: "percentage", value: 20
// or valid: false, error: "Invalid discount code"Affiliates
Build a referral program for your product. Affiliates sign up, get a unique referral code, and earn commissions on referred purchases.
Dashboard
Navigate to Grow → Affiliates to manage your program. From here you can:
- Enable or disable the affiliate program
- Set commission type (percentage or fixed) and value
- Configure cookie duration and minimum payout amount
- Choose approval mode (manual or auto-approve)
- View and approve/reject affiliate applications
- Track referrals, conversions, and commissions
- Process payouts
How It Works
- 1Affiliate signs up with their email, name, website, and how they plan to promote your product.
- 2You approve the application (or auto-approve based on your settings). The affiliate receives a unique referral code.
- 3Affiliate shares their link containing the referral code. A tracking cookie is set when a visitor clicks through.
- 4Visitor converts (signs up, purchases, etc.). The referral is attributed to the affiliate and a commission is calculated.
- 5You process payouts once commissions reach the minimum payout threshold.
Settings Reference
| Setting | Default | Description |
|---|---|---|
| commission_type | percentage | percentage or fixed |
| commission_value | 20 | 20% per referred sale (or $20 if fixed) |
| cookie_duration_days | 30 | How long the referral cookie persists |
| min_payout_amount | $50 | Minimum earned before payout is available |
| approval_mode | manual | manual or auto |
Webhooks
Receive real-time notifications when events happen in your connected payment provider (Stripe or Polar.sh). Webhooks are automatically configured when you connect a payment provider.
Webhook URL
When connecting a payment provider, CreateaSaaS generates a unique webhook URL for your project. Add this URL to your Stripe or Polar.sh dashboard to receive events.
https://your-domain.com/api/webhooks/payment/{projectId}/{provider}Supported Events
| Event | Description |
|---|---|
| customer.created | New customer added |
| subscription.created | New subscription started |
| subscription.updated | Subscription plan/status changed |
| charge.succeeded | Payment completed successfully |
| charge.refunded | Payment refunded |
Security
All webhook payloads are verified using the webhook secret you provide when connecting a payment provider. CreateaSaaS validates the signature before processing any event, preventing spoofed requests.
API Reference
Complete list of public API endpoints. All endpoints require a publishable key (mh_pk_...) passed via the Authorization header or data-key attribute.
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /api/sdk/v1/analytics/track | Publishable | Track an event |
| POST | /api/sdk/v1/heatmap/track | Publishable | Track heatmap data |
| POST | /sdk/v1/recordings/start | Publishable | Start a recording session. Params: visitor_id, page_url, viewport_width, viewport_height |
| POST | /sdk/v1/recordings/chunk | Publishable | Upload a chunk of recording events. Params: recording_id, chunk_index, events (rrweb event array) |
| POST | /sdk/v1/recordings/stop | Publishable | Finalize a recording. Params: recording_id, duration_ms, total_events |
| POST | /api/sdk/v1/support/submit | Publishable | Submit support ticket |
| GET | /api/sdk/v1/blog/posts | Publishable | List published blog posts |
| GET | /api/sdk/v1/blog/posts/:slug | Publishable | Get single blog post |
| GET | /api/sdk/v1/announcements | Publishable | List published announcements |
| GET | /api/sdk/v1/pricing/plans | Publishable | List pricing plans |
| POST | /api/sdk/v1/discounts/validate | Publishable | Validate discount code |
| GET | /api/sdk/v1/ab/assign/:id | Publishable | Get A/B test assignment |
| POST | /api/sdk/v1/ab/convert/:id | Publishable | Record A/B conversion |
| POST | /api/sdk/v1/auth/signup | Publishable | Sign up end user |
| POST | /api/sdk/v1/auth/signin | Publishable | Sign in end user |
Ready to integrate?
Create your first project and start sending events in under five minutes.