Package Exports
- @practicestack/leads
Readme
@practicestack/leads
Lightweight JavaScript SDK to capture leads from any website and push them directly into your PracticeStacks account. Zero dependencies, works everywhere — React, Next.js, Vue, vanilla HTML, or any website.
Quick Start
1. Get Your API Token
Go to PracticeStacks > Settings > API Tokens > Create Token with LEADS_WRITE scope.
2. Install
npm / bun / yarn:
npm i @practicestack/leadsCDN (no build tool needed):
<script src="https://cdn.jsdelivr.net/npm/@practicestack/leads/dist/index.global.js"></script>3. Capture Leads
ES Modules (React, Next.js, Vue, etc.):
import PracticeStack from "@practicestack/leads";
PracticeStack.init({ token: "ps_live_xxxxx" });
const result = await PracticeStack.captureLead({
name: "John Doe",
email: "john@example.com",
phone: "9876543210",
source: "Website Contact Form",
});
if (result.success) {
console.info("Lead captured:", result.lead.id);
} else {
console.error("Error:", result.error);
}Script tag (any HTML website):
<script src="https://cdn.jsdelivr.net/npm/@practicestack/leads/dist/index.global.js"></script>
<script>
PracticeStack.init({ token: "ps_live_xxxxx" });
document
.getElementById("contactForm")
.addEventListener("submit", async function (e) {
e.preventDefault();
const result = await PracticeStack.captureLead({
name: document.getElementById("name").value,
email: document.getElementById("email").value,
phone: document.getElementById("phone").value,
source: "Website Contact Form",
});
if (result.success) {
alert("Thank you! We will get back to you soon.");
}
});
</script>API Reference
PracticeStack.init(config)
Initialize the SDK. Must be called before captureLead().
| Parameter | Type | Required | Description |
|---|---|---|---|
token |
string |
Yes | Your API token from PracticeStacks Settings |
baseUrl |
string |
No | Override API URL (default: https://www.practicestacks.in). Use http://localhost:4444 for local testing against a dev server. |
PracticeStack.captureLead(data)
Capture a lead and push it to your PracticeStack account. Returns a Promise<CaptureResult>.
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string |
Yes | Lead/company name |
email |
string |
No | Contact email address |
phone |
string |
No | Contact phone number |
source |
string |
No | Where the lead came from (default: "Website") |
notes |
string |
No | Additional notes or message from the form |
tags |
string[] |
No | Tags for categorization (e.g., ["website", "urgent"]) |
Response:
// Success
{
success: true,
lead: {
id: "clx...",
companyName: "John Doe",
companyEmail: "john@example.com",
companyPhone: "9876543210",
source: "Website Contact Form",
status: "NEW",
createdAt: "2026-03-20T..."
}
}
// Error
{
success: false,
error: "Name is required"
}PracticeStack.reset()
Reset the SDK configuration. Useful for testing or switching tokens.
Full Example: Contact Form
<!DOCTYPE html>
<html>
<head>
<title>Contact Us</title>
</head>
<body>
<h1>Contact Us</h1>
<form id="contactForm">
<input type="text" id="name" placeholder="Your Name" required />
<input type="email" id="email" placeholder="Email" />
<input type="tel" id="phone" placeholder="Phone" />
<textarea id="message" placeholder="Your message"></textarea>
<button type="submit">Send</button>
</form>
<script src="https://cdn.jsdelivr.net/npm/@practicestack/leads/dist/index.global.js"></script>
<script>
PracticeStack.init({ token: "ps_live_xxxxx" });
document
.getElementById("contactForm")
.addEventListener("submit", async function (e) {
e.preventDefault();
var btn = this.querySelector("button");
btn.disabled = true;
btn.textContent = "Sending...";
var result = await PracticeStack.captureLead({
name: document.getElementById("name").value,
email: document.getElementById("email").value,
phone: document.getElementById("phone").value,
notes: document.getElementById("message").value,
source: "Website Contact Form",
});
if (result.success) {
btn.textContent = "Sent!";
this.reset();
} else {
btn.textContent = "Send";
btn.disabled = false;
alert("Something went wrong. Please try again.");
}
});
</script>
</body>
</html>Error Handling
| Error | Cause |
|---|---|
"PracticeStack SDK not initialized..." |
Forgot to call PracticeStack.init() |
"Name is required" |
name field is empty |
"Invalid API token" |
Token is wrong or doesn't exist |
"API token has been revoked" |
Token was revoked in PracticeStacks settings |
"API token has expired" |
Token has passed its expiry date |
"API token does not have LEADS_WRITE permission" |
Token is missing the LEADS_WRITE scope |
Local Testing
Point the SDK at a local PracticeStacks dev server:
PracticeStack.init({
token: "ps_test_xxxxx",
baseUrl: "http://localhost:4444",
});Steps:
- Run PracticeStacks locally —
bun devin thepractice-stackrepo (serves on port4444). - Sign in, go to Settings > API Tokens > Create Token, pick
LEADS_WRITEscope. - Use that token +
baseUrl: 'http://localhost:4444'inPracticeStack.init(). captureLead()POSTs tohttp://localhost:4444/api/v1/leads/capture. The endpoint already sets permissive CORS, so browser calls from any origin work.
Note on the platform host. The production SaaS lives at
https://www.practicestacks.in— that is the value you should use forbaseUrlin production (and it is the default). There is noapp.practicestack.comorapp.practicestacks.comhost; older docs that referenced those subdomains were incorrect.
Requirements
- A PracticeStacks account
- An API token with
LEADS_WRITEscope
License
MIT