@cstar.help/js
v0.10.3
Published
Official TypeScript SDK for the cStar customer support platform
Maintainers
Readme
@cstar.help/js
Official TypeScript SDK for the cStar customer support platform.
- Zero dependencies — works with Node.js 18+ native
fetch - TypeScript-first — full type definitions included
- Six entry points — tree-shake what you don't need
- ESM + CJS — works everywhere
Install
npm install @cstar.help/jsWhich SDK Do I Need?
cStar has one package with six entry points, each designed for a different context:
| Import | Use Case | Runs On | Auth Required | Key Type |
| -------------------------- | ----------------------------------------- | ----------------- | ------------- | -------------------- |
| @cstar.help/js | Admin dashboard / backend integration | Server only | Yes | Secret (sk_*) |
| @cstar.help/js/chat | Customer chat widget | Browser | Yes | Publishable (pk_*) |
| @cstar.help/js/library | Public knowledge base | Browser or server | No | None |
| @cstar.help/js/community | Public community forum | Browser or server | No | None |
| @cstar.help/js/webhook | Webhook signature verification | Server only | No | Signing secret |
| @cstar.help/js/auth | Authentication utilities | Server only | Yes | Secret (sk_*) |
The Security Model
cStar uses two key types to control access — the same pattern as Stripe and Supabase:
Secret keys (sk_live_*, sk_test_*)
├── Full CRUD on all resources
├── Settings, billing, analytics, game system
├── Team member management, audit log
├── AI actions, automations, SLA rules
└── NEVER expose in client-side code
Publishable keys (pk_live_*, pk_test_*)
├── Read-only on public data (tickets, customers, articles)
├── Used by the chat widget for customer-facing features
├── Safe to include in browser bundles
└── Cannot write, delete, or access sensitive endpointsRule of thumb: If you're building a custom support dashboard for your team, use
CStarClientwith a secret key on your backend. If you're adding chat to your website, useChatClientwith a publishable key in the browser.
Server-Side: Admin API Client
⚠️ Server-side only.
CStarClientrequires a secret key (sk_*) and must never be used in browser code. The SDK will warn you if it detects a browser environment.
Manage tickets, customers, articles, team members, settings, game system, and everything else.
import { CStarClient } from '@cstar.help/js';
const cstar = new CStarClient({
apiKey: process.env.CSTAR_SECRET_KEY, // sk_live_... or sk_test_...
teamId: process.env.CSTAR_TEAM_ID
});
// List open tickets
const { data: tickets } = await cstar.tickets.list({ status: 'open' });
// Create a ticket
const { data: ticket } = await cstar.tickets.create({
title: 'Help with billing',
customerId: 'cus_abc123'
});
// Auto-paginate through all tickets
for await (const ticket of cstar.tickets.listAutoPaginating({ status: 'open' })) {
console.log(ticket.title);
}Full Resource Reference
Core Resources — Tickets, customers, and knowledge base.
| Resource | Methods |
| ------------------------ | ----------------------------------------------------------------------------------------------- |
| cstar.tickets | .list() .get(id) .create(params) .update(id, params) .del(id) .listAutoPaginating() |
| cstar.tickets.messages | .list(ticketId) .create(ticketId, params) |
| cstar.customers | .list() .get(id) .create(params) .update(id, params) .del(id) .listAutoPaginating() |
| cstar.articles | .list() .get(id) .create(params) .update(id, params) .del(id) .listAutoPaginating() |
| cstar.categories | .list() .get(id) .create(params) .update(id, params) .del(id) |
Team & Configuration — Members, settings, and customization.
| Resource | Methods |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| cstar.members | .list() .get(id) .update(id, params) .del(id) |
| cstar.members.invites | .list() .create(params) .del(id) |
| cstar.settings | .get() .update(params) .getBusinessHours() .updateBusinessHours(params) .getWidget() .updateWidget(params) |
| cstar.settings.statuses | .list() .create(params) .update(key, params) .del(key) .reorder(keys) |
| cstar.settings.quickReplies | .list() .create(params) .update(id, params) .del(id) .reorder(ids) |
| cstar.customFields | .list() .get(id) .create(params) .update(id, params) .del(id) .reorder(ids) |
| cstar.notifications | .list() .unreadCount() .markRead(id) .markAllRead() |
Operations — Analytics, bulk actions, and data management.
| Resource | Methods |
| ---------------------- | --------------------------------------------------------------------------------------- |
| cstar.analytics | .overview(params?) .agents(params?) .csatStats(params?) .csatResponses(params?) |
| cstar.sla | .list() .get(id) .create(params) .update(id, params) .del(id) |
| cstar.bulk | .update(params) .del(params) |
| cstar.export | .create(params) |
| cstar.import | .create(params) .logs(params?) .getLog(id) |
| cstar.search | .query(params) |
| cstar.tags | .list() .create(name) .del(name) |
| cstar.activity | .list(params?) |
| cstar.auditLog | .list(params?) |
| cstar.customerGroups | .list() .get(id) .create(params) .update(id, params) .del(id) |
Gamification — The full game system.
| Resource | Methods |
| ------------------------- | --------------------------------------------------------------------------------------------------- |
| cstar.game | .player(params?) .getPlayer(memberId) .leaderboard(params?) .myRank(params?) |
| cstar.game.boss | .current() .isActive() .spawn(params?) .damage(params) .defeats(params?) .getDefeat(id) |
| cstar.game.achievements | .list(params?) .unlocked(params) .get(id, params?) |
| cstar.game.quests | .today(params?) .history(params?) |
| cstar.game.puzzles | .today(params?) .complete(params) .streak(params) .leaderboard(params?) |
| cstar.game.oneUps | .list(params?) .send(params) .remaining(params) |
| cstar.game.highFives | .list(params?) .send(params) .canSend(teamId, params) |
| cstar.game.cosmetics | .list(params?) .getPreferences(params) .updatePreferences(params) |
| cstar.game.seasons | .list() .current() .stats(seasonId, params) |
| cstar.game.skills | .get(params) .allocate(params) .reset(params) |
Advanced — AI, automations, views, billing, webhooks.
| Resource | Methods |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| cstar.ai | .run(params) .autoTag(ticketId) .suggestReply(ticketId) .summarize(ticketId) .improve(text) |
| cstar.automations | .list() .get(id) .create(params) .update(id, params) .del(id) .toggle(id) .reorder(ids) .test(id, params) .executions(id) .allExecutions() .evaluate(params) |
| cstar.views | .list() .get(id) .create(params) .update(id, params) .del(id) .execute(id, params?) |
| cstar.billing | .subscription() .portal(params?) |
| cstar.webhooks | .list() .get(id) .create(params) .update(id, params) .del(id) .test(id) |
| cstar.community.posts | .list() .get(id) .create(params) .update(id, params) .del(id) |
| cstar.community.topics | .list() .get(id) |
| cstar.attachments | .list(params?) .get(id) .del(id) |
Usage Examples
// Team analytics
const { data: overview } = await cstar.analytics.overview({ period: 'week' });
console.log(`${overview.tickets.open} open tickets this week`);
// SLA rules
const { data: rules } = await cstar.sla.list();
// Boss battle
const { data: boss } = await cstar.game.boss.current();
if (boss.active) {
console.log(`${boss.name} — ${boss.health}/${boss.maxHealth} HP`);
}
// AI-powered reply suggestion
const { data: suggestion } = await cstar.ai.suggestReply('tkt_abc123');
// Bulk close resolved tickets
await cstar.bulk.update({
resource: 'tickets',
ids: ['tkt_1', 'tkt_2', 'tkt_3'],
data: { status: 'closed' }
});
// Export data
const { data: exportResult } = await cstar.export.create({
resources: [{ type: 'tickets', filters: { status: 'closed' } }],
format: 'csv'
});
// Saved views
const { data: view } = await cstar.views.create({
name: 'Urgent Unresolved',
entityType: 'tickets',
filters: { priority: 'urgent', status: 'open' }
});
const { data: results } = await cstar.views.execute(view.id);
// Search across everything
const { data: searchResults } = await cstar.search.query({
query: 'billing issue',
types: ['tickets', 'customers']
});Client-Side: Chat Widget SDK
Build custom chat experiences in the browser. Uses a publishable key — safe for frontend code.
import { ChatClient } from '@cstar.help/js/chat';
const chat = new ChatClient({ teamSlug: 'acme' });
// Identify the customer (HMAC signature from your server)
await chat.identify(
{ externalId: 'usr_123', email: '[email protected]', name: 'Jane', timestamp: Date.now() / 1000 },
hmacSignature
);
// List conversations
const { conversations } = await chat.conversations.list();
// Send a message
await chat.messages.send('tkt_abc123', 'Thanks for the help!');
// Subscribe to new messages
const unsubscribe = chat.onMessage('tkt_abc123', (message) => {
console.log(`${message.sender_name}: ${message.content}`);
});
// Clean up
chat.disconnect();Client-Side: Public Knowledge Base
Search and browse your public help center — no authentication required.
import { LibraryClient } from '@cstar.help/js/library';
const library = new LibraryClient({ teamSlug: 'acme' });
const categories = await library.categories();
const results = await library.search('reset password');
const article = await library.article('how-to-reset-password');Client-Side: Public Community
Browse your public community forum — no authentication required.
import { CommunityClient } from '@cstar.help/js/community';
const community = new CommunityClient({ teamSlug: 'acme' });
const topics = await community.topics();
const { posts } = await community.posts({ topicSlug: 'feature-requests', sort: 'votes' });
const { post, comments } = await community.post('dark-mode-support');Server-Side: Webhook Verification
Verify incoming webhook signatures on your server.
import { constructEvent } from '@cstar.help/js/webhook';
// In your webhook handler
const event = constructEvent(rawBody, signature, 'whsec_your_secret');
switch (event.type) {
case 'ticket.created':
console.log('New ticket:', event.data.title);
break;
case 'customer.created':
console.log('New customer:', event.data.email);
break;
}For edge runtimes (Cloudflare Workers, Deno), use the async variant:
import { constructEventAsync } from '@cstar.help/js/webhook';
const event = await constructEventAsync(rawBody, signature, secret);Configuration
const cstar = new CStarClient({
apiKey: 'sk_live_...', // Required — must be a secret key (sk_*)
teamId: 'tm_...', // Required — your team ID
baseUrl: 'https://...', // Optional — defaults to https://www.cstar.help
version: '2026-03-01', // Optional — API version header
maxRetries: 3, // Optional — retry attempts for 5xx/429
timeout: 30000 // Optional — request timeout in ms
});Test Mode
Test mode is auto-detected from your API key prefix:
const cstar = new CStarClient({
apiKey: 'sk_test_abc123...',
teamId: 'tm_your_team_id'
});
console.log(cstar.isTestMode); // true
// All operations use test data — no real customers affectedError Handling
All API errors throw typed exceptions:
import {
CStarError,
CStarAuthenticationError,
CStarRateLimitError,
CStarNotFoundError,
CStarValidationError
} from '@cstar.help/js';
try {
await cstar.tickets.get('tkt_nonexistent');
} catch (err) {
if (err instanceof CStarNotFoundError) {
console.log('Ticket not found:', err.message);
} else if (err instanceof CStarValidationError) {
console.log('Invalid param:', err.param);
} else if (err instanceof CStarRateLimitError) {
console.log('Rate limited, retry after:', err.retryAfter, 'seconds');
} else if (err instanceof CStarAuthenticationError) {
console.log('Bad API key');
} else if (err instanceof CStarError) {
console.log('API error:', err.code, err.statusCode);
}
}Idempotency
Safely retry create/update operations:
const { data: ticket } = await cstar.tickets.create(
{ title: 'Billing issue', customerId: 'cus_abc' },
{ idempotencyKey: 'create-billing-issue-usr123' }
);Requirements
- Node.js 18+ (for native
fetchandAbortSignal.timeout) - TypeScript 5.0+ (for type definitions)
License
MIT
