@codeswayam/api-client
v1.3.4
Published
CodeSwayam Professional SaaS SDK
Readme
@codeswayam/api-client
The canonical HTTP client and TypeScript SDK for all CodeSwayam API interactions.
@codeswayam/api-client is the low-level HTTP SDK that powers every CodeSwayam application. It wraps the CodeSwayam REST API with typed functions and a class-based SDK interface, handling authentication headers, cookie credentials, and response parsing so your app code never has to.
Table of Contents
- Overview
- Installation
- Peer Dependencies
- Authentication
- SDK Class
- API Reference
- TypeScript Types
- Code Examples
- Integration Guide (Next.js)
- Error Handling
- Changelog
Overview
@codeswayam/api-client is the foundation layer of the CodeSwayam SDK stack:
@codeswayam/auth — Auth, guards, SSO, notifications
↓
@codeswayam/access — Entitlements, feature gates, usage
↓
@codeswayam/api-client — HTTP client, types, raw API functionsAll packages in the CodeSwayam ecosystem call into @codeswayam/api-client for network requests. You can use this package directly for advanced use cases, admin tooling, or building custom integrations.
Key design decisions:
| Decision | Detail |
|---|---|
| HTTP library | Axios — consistent request/response interceptors |
| Auth strategy | Dual: credentials: 'include' (cookie) + Authorization: Bearer header fallback |
| Token source | localStorage via getAuthHeaders() |
| TypeScript | All functions and types are fully typed |
| Tree-shaking | Named exports only — import only what you use |
Installation
npm install @codeswayam/api-client
# or
yarn add @codeswayam/api-client
# or
pnpm add @codeswayam/api-clientPeer Dependencies
| Package | Version |
|---|---|
| axios | ^1.0.0 |
npm install axiosAuthentication
All API functions in this package authenticate using a dual strategy:
1. HTTP Cookies (primary)
All requests are made with withCredentials: true, which sends the csw_session HttpOnly cookie automatically if present.
2. Bearer Token (fallback)
getAuthHeaders() reads the JWT from localStorage and returns an Authorization header. Used as a fallback when cookies are unavailable (e.g. cross-origin requests).
import { getAuthHeaders } from '@codeswayam/api-client';
// Returns: { Authorization: 'Bearer eyJ...' }
// Returns: {} if no token is stored
const headers = getAuthHeaders();The token is stored under the key CSW_TOKEN_KEY (re-exported from @codeswayam/auth).
CodeSwayamSDK Class
For applications that need a configured SDK instance (e.g. with a custom base URL), use the CodeSwayamSDK class.
import { CodeSwayamSDK } from '@codeswayam/api-client';
const sdk = new CodeSwayamSDK({
baseUrl: 'https://api.codeswayam.com',
});
// Generic request method
const data = await sdk.request<ResponseType>({
method: 'GET',
path: '/v1/some-endpoint',
params: { foo: 'bar' },
});
// Namespaced API groups
const profile = await sdk.auth.getProfile();
const entitlements = await sdk.entitlements.fetchMyEntitlements('auraflow');Constructor options:
| Option | Type | Required | Description |
|---|---|---|---|
| baseUrl | string | ✅ | Base URL for all API requests |
| timeout | number | — | Request timeout in ms (default: 10000) |
| headers | Record<string, string> | — | Additional headers for every request |
SDK namespaces:
| Namespace | Methods |
|---|---|
| sdk.auth | getProfile, login, logout, getUsersBatch |
| sdk.entitlements | fetchMyEntitlements, trackUsage, getAllAppsEntitlements |
API Reference
Auth Functions
import {
getProfile,
login,
logout,
getUsersBatch,
} from '@codeswayam/api-client';| Function | Signature | Description |
|---|---|---|
| getProfile | () => Promise<CSWUser> | Fetch the authenticated user's profile |
| login | (email: string, password: string) => Promise<{ token: string; user: CSWUser }> | Email/password login (non-SSO apps) |
| logout | () => Promise<void> | Invalidate the current session |
| getUsersBatch | (userIds: string[]) => Promise<CSWUser[]> | Fetch multiple user profiles by ID |
Subscription Functions
import {
fetchUserSubscriptions,
fetchSubscriptionById,
fetchPublicPlans,
changeSubscriptionPlan,
cancelUserSubscription,
} from '@codeswayam/api-client';| Function | Signature | Description |
|---|---|---|
| fetchUserSubscriptions | () => Promise<UserSubscription[]> | All subscriptions for the authenticated user |
| fetchSubscriptionById | (id: string) => Promise<UserSubscription> | Single subscription by ID |
| fetchPublicPlans | (appId?: string) => Promise<SaasProduct[]> | Publicly listed plans (for pricing pages) |
| changeSubscriptionPlan | (subscriptionId: string, newPlanId: string) => Promise<UserSubscription> | Upgrade or downgrade a subscription |
| cancelUserSubscription | (subscriptionId: string) => Promise<void> | Cancel a subscription |
Credit Functions
import {
fetchMyWallet,
useCredits,
fetchCreditPacks,
fetchFeatureCosts,
createCreditPurchaseOrder,
verifyCreditPurchase,
} from '@codeswayam/api-client';| Function | Signature | Description |
|---|---|---|
| fetchMyWallet | () => Promise<UserWalletResponse> | Current balance, transactions, and feature costs |
| useCredits | (feature: string) => Promise<CreditTransaction> | Deduct credits for a feature use |
| fetchCreditPacks | () => Promise<CreditPack[]> | Available credit packs for purchase |
| fetchFeatureCosts | () => Promise<FeatureCreditCost[]> | Per-feature credit cost table |
| createCreditPurchaseOrder | (packId: string) => Promise<{ orderId: string; amount: number; currency: string }> | Create a Razorpay order for a credit pack |
| verifyCreditPurchase | (payload: VerifyPurchasePayload) => Promise<UserWalletResponse> | Verify a Razorpay payment and credit the wallet |
Referral Functions
import {
fetchReferralStats,
redeemReferralCode,
redeemCouponCode,
} from '@codeswayam/api-client';| Function | Signature | Description |
|---|---|---|
| fetchReferralStats | () => Promise<ReferralStats> | Referral link, history, and earned rewards |
| redeemReferralCode | (code: string) => Promise<{ creditsEarned: number }> | Apply a friend's referral code |
| redeemCouponCode | (code: string) => Promise<{ creditsEarned: number; discount?: number }> | Apply a promotional coupon code |
Entitlement Functions
The core functions consumed by @codeswayam/access. You can call these directly for server-side data fetching.
import {
fetchMyEntitlements,
trackUsage,
getAllAppsEntitlements,
} from '@codeswayam/api-client';| Function | Signature | Description |
|---|---|---|
| fetchMyEntitlements | (appId: string) => Promise<EntitlementResult> | Full entitlements for a specific app |
| trackUsage | (payload: TrackUsagePayload) => Promise<TrackUsageResult> | Increment a usage counter |
| getAllAppsEntitlements | () => Promise<AppEntitlementSummary[]> | Entitlements across all apps (admin / dashboard use) |
TrackUsagePayload:
interface TrackUsagePayload {
appId: string;
counterKey: string;
increment?: number; // defaults to 1
}Notification Functions
import {
registerPushSubscription,
unregisterPushSubscription,
fetchVapidPublicKey,
sendNotificationCampaign,
fetchNotificationCampaigns,
fetchNotificationStats,
deleteNotificationCampaign,
} from '@codeswayam/api-client';| Function | Signature | Description |
|---|---|---|
| fetchVapidPublicKey | () => Promise<{ publicKey: string }> | Fetch the VAPID public key for Web Push |
| registerPushSubscription | (subscription: PushSubscription) => Promise<void> | Register a browser push subscription |
| unregisterPushSubscription | (endpoint: string) => Promise<void> | Remove a push subscription |
| sendNotificationCampaign | (payload: NotificationPayload) => Promise<NotificationCampaign> | Send a push notification campaign (admin) |
| fetchNotificationCampaigns | () => Promise<NotificationCampaign[]> | List all notification campaigns (admin) |
| fetchNotificationStats | (campaignId: string) => Promise<NotificationStats> | Delivery and click stats for a campaign (admin) |
| deleteNotificationCampaign | (campaignId: string) => Promise<void> | Delete a notification campaign (admin) |
Admin Functions
Admin-only functions. All require the caller to have an admin role; the API will return 403 otherwise.
import {
// User admin
adminListUsers,
adminGetUser,
adminUpdateUser,
adminDeleteUser,
// Subscription admin
adminListSubscriptions,
adminUpdateSubscription,
// Credit admin
adminAdjustCredits,
adminListCreditTransactions,
// Settings admin
adminGetSettings,
adminUpdateSettings,
} from '@codeswayam/api-client';| Function | Description |
|---|---|
| adminListUsers | Paginated list of all users |
| adminGetUser(userId) | Fetch a single user by ID |
| adminUpdateUser(userId, data) | Update user fields (role, name, etc.) |
| adminDeleteUser(userId) | Permanently delete a user account |
| adminListSubscriptions | List all subscriptions (all users) |
| adminUpdateSubscription(id, data) | Override subscription fields |
| adminAdjustCredits(userId, amount, reason) | Manually add or remove credits |
| adminListCreditTransactions | Paginated credit transaction log |
| adminGetSettings | Fetch platform-wide settings |
| adminUpdateSettings(settings) | Update platform settings |
TypeScript Types
All types are exported from the package root:
import type {
// Products & subscriptions
SaasProduct,
UserSubscription,
// Credits
CreditPack,
UserCredits,
CreditTransaction,
FeatureCreditCost,
UserWalletResponse,
// Referrals
ReferralStats,
ReferralHistoryItem,
// Entitlements
EntitlementResult,
AppEntitlementSummary,
TrackUsagePayload,
TrackUsageResult,
UsageSummary,
// Notifications
NotificationPayload,
NotificationCampaign,
NotificationStats,
} from '@codeswayam/api-client';Interface Definitions
interface SaasProduct {
id: string;
name: string;
appId: string;
planType: string; // e.g. "pro_monthly"
billingCycle: 'monthly' | 'annual';
price: number;
currency: string;
features: Record<string, boolean | number>;
isActive: boolean;
}
interface UserSubscription {
id: string;
userId: string;
productId: string;
appId: string;
status: 'active' | 'cancelled' | 'expired' | 'trialing';
planType: string;
billingCycle: 'monthly' | 'annual';
currentPeriodStart: string;
currentPeriodEnd: string;
expiresAt: string | null;
cancelledAt: string | null;
}
interface CreditPack {
id: string;
name: string;
credits: number;
price: number;
currency: string;
bonus?: number; // Bonus credits for promotional packs
isPopular?: boolean;
}
interface UserCredits {
userId: string;
balance: number;
lifetimeEarned: number;
lifetimeSpent: number;
}
interface CreditTransaction {
id: string;
userId: string;
type: 'earned' | 'spent' | 'purchased' | 'adjusted' | 'refunded';
amount: number;
feature?: string;
description: string;
createdAt: string;
}
interface FeatureCreditCost {
featureKey: string;
cost: number;
appId?: string;
}
interface UserWalletResponse {
credits: UserCredits;
recentTransactions: CreditTransaction[];
featureCosts: FeatureCreditCost[];
}
interface ReferralStats {
referralCode: string;
referralUrl: string;
totalReferrals: number;
creditsEarned: number;
history: ReferralHistoryItem[];
}
interface ReferralHistoryItem {
id: string;
referredUserId: string;
referredUserName: string;
creditsEarned: number;
createdAt: string;
}
interface EntitlementResult {
appId: string;
userId: string;
role: string;
tier: {
name: string;
label: string;
aiIncluded: boolean;
};
subscription: {
id: string;
status: string;
planType: string;
expiresAt: string | null;
billingCycle: string;
} | null;
credits: {
balance: number;
featureCosts: Record<string, number>;
};
usage: Record<string, UsageSummary>;
features: Record<string, boolean | number>;
}
interface AppEntitlementSummary {
appId: string;
tier: string;
hasActivePlan: boolean;
usageSummaries: Record<string, UsageSummary>;
}
interface TrackUsagePayload {
appId: string;
counterKey: string;
increment?: number;
}
interface TrackUsageResult {
counterKey: string;
used: number;
limit: number;
remaining: number;
percentage: number;
}
interface UsageSummary {
used: number;
limit: number;
remaining: number;
percentage: number;
}
interface NotificationPayload {
title: string;
body: string;
icon?: string;
url?: string;
targetUserIds?: string[]; // empty = broadcast to all
appId?: string;
}
interface NotificationCampaign {
id: string;
title: string;
body: string;
sentAt: string;
targetCount: number;
deliveredCount: number;
status: 'pending' | 'sent' | 'failed';
}
interface NotificationStats {
campaignId: string;
sent: number;
delivered: number;
clicked: number;
failed: number;
deliveryRate: number;
clickRate: number;
}Code Examples
1. SDK Initialization
import { CodeSwayamSDK } from '@codeswayam/api-client';
// Create a configured SDK instance
export const sdk = new CodeSwayamSDK({
baseUrl: process.env.NEXT_PUBLIC_API_URL ?? 'https://api.codeswayam.com',
timeout: 15_000,
});
// Use throughout your app
export default sdk;Or use standalone functions (recommended for tree-shaking):
// Import only what you need
import { fetchMyEntitlements, trackUsage } from '@codeswayam/api-client';2. fetchMyEntitlements Usage
import { fetchMyEntitlements } from '@codeswayam/api-client';
// Fetch full entitlements for the 'auraflow' app
async function loadAccess() {
const entitlements = await fetchMyEntitlements('auraflow');
console.log('Tier:', entitlements.tier.name);
console.log('DM usage:', entitlements.usage['dms']);
console.log('AI chat feature:', entitlements.features['ai_chat']);
}
// Server-side usage in Next.js (App Router)
import { cookies } from 'next/headers';
export async function getUserEntitlements(appId: string) {
// fetchMyEntitlements uses cookies: 'include' — works server-side
// when the request context has the session cookie
return fetchMyEntitlements(appId);
}3. trackUsage Usage
import { trackUsage } from '@codeswayam/api-client';
// Track a single DM send
async function onMessageSent() {
const result = await trackUsage({
appId: 'auraflow',
counterKey: 'dms',
increment: 1, // optional, defaults to 1
});
console.log(`DMs used: ${result.used}/${result.limit}`);
if (result.remaining === 0) {
showUpgradePrompt();
}
}
// Track a bulk operation
async function onBulkExport(count: number) {
const result = await trackUsage({
appId: 'auraflow',
counterKey: 'exports',
increment: count,
});
return result;
}4. fetchMyWallet + useCredits
import { fetchMyWallet, useCredits } from '@codeswayam/api-client';
// Load the wallet on component mount
async function initWallet() {
const wallet = await fetchMyWallet();
console.log('Balance:', wallet.credits.balance);
console.log('AI chat costs:', wallet.featureCosts.find(f => f.featureKey === 'ai_chat')?.cost);
return wallet;
}
// Deduct credits when a feature is used
async function consumeAiCredit() {
try {
const transaction = await useCredits('ai_chat');
console.log('Credits deducted:', transaction.amount);
console.log('New balance available via fetchMyWallet()');
} catch (error) {
// API returns 402 when balance is insufficient
if ((error as any).response?.status === 402) {
console.error('Insufficient credits');
showBuyCreditsModal();
}
}
}5. Push Notification Registration
import {
fetchVapidPublicKey,
registerPushSubscription,
unregisterPushSubscription,
} from '@codeswayam/api-client';
// Register the browser for push notifications
async function enablePushNotifications() {
// 1. Check browser support
if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
console.warn('Push notifications not supported');
return;
}
// 2. Request permission
const permission = await Notification.requestPermission();
if (permission !== 'granted') return;
// 3. Fetch VAPID public key from server
const { publicKey } = await fetchVapidPublicKey();
// 4. Get push subscription from browser
const registration = await navigator.serviceWorker.ready;
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: publicKey,
});
// 5. Register with CodeSwayam API
await registerPushSubscription(subscription);
console.log('Push notifications enabled');
}
// Unregister
async function disablePushNotifications(endpoint: string) {
await unregisterPushSubscription(endpoint);
console.log('Push notifications disabled');
}6. CodeSwayamSDK Class Usage
import { CodeSwayamSDK } from '@codeswayam/api-client';
const sdk = new CodeSwayamSDK({
baseUrl: 'https://api.codeswayam.com',
});
// Using namespaced methods
async function bootstrap(appId: string) {
const [profile, entitlements] = await Promise.all([
sdk.auth.getProfile(),
sdk.entitlements.fetchMyEntitlements(appId),
]);
return { profile, entitlements };
}
// Using the generic request method for custom endpoints
async function fetchCustomData<T>(path: string): Promise<T> {
return sdk.request<T>({
method: 'GET',
path,
});
}
// POST with body
async function postCustomData<T>(path: string, body: unknown): Promise<T> {
return sdk.request<T>({
method: 'POST',
path,
data: body,
});
}7. Subscription Management
import {
fetchUserSubscriptions,
fetchPublicPlans,
changeSubscriptionPlan,
cancelUserSubscription,
} from '@codeswayam/api-client';
// Load current subscriptions + available plans
async function loadSubscriptionPage(appId: string) {
const [subscriptions, plans] = await Promise.all([
fetchUserSubscriptions(),
fetchPublicPlans(appId),
]);
const active = subscriptions.find(
s => s.appId === appId && s.status === 'active'
);
return { active, plans };
}
// Upgrade subscription
async function upgradeToPro(subscriptionId: string, proPlanId: string) {
const updated = await changeSubscriptionPlan(subscriptionId, proPlanId);
console.log('Upgraded to:', updated.planType);
return updated;
}
// Cancel subscription
async function cancelPlan(subscriptionId: string) {
await cancelUserSubscription(subscriptionId);
console.log('Subscription cancelled');
}8. Admin: Adjust Credits
import { adminAdjustCredits } from '@codeswayam/api-client';
// Grant 100 bonus credits to a user (admin only)
async function grantBonusCredits(userId: string) {
await adminAdjustCredits(userId, 100, 'Promotional bonus — Q4 campaign');
console.log('Credited 100 bonus credits to user', userId);
}
// Deduct credits as penalty (negative amount)
async function deductCredits(userId: string) {
await adminAdjustCredits(userId, -50, 'Chargeback adjustment');
}Integration Guide (Next.js)
Server-Side Data Fetching (App Router)
// app/dashboard/page.tsx
import { fetchMyEntitlements } from '@codeswayam/api-client';
export default async function DashboardPage() {
// Server Component — runs on the server with the user's cookie
const entitlements = await fetchMyEntitlements('auraflow');
return (
<main>
<p>Tier: {entitlements.tier.label}</p>
<p>Credits: {entitlements.credits.balance}</p>
</main>
);
}API Route Handler
// app/api/usage/route.ts
import { trackUsage } from '@codeswayam/api-client';
import { NextRequest, NextResponse } from 'next/server';
export async function POST(req: NextRequest) {
const { appId, counterKey, increment } = await req.json();
const result = await trackUsage({ appId, counterKey, increment });
return NextResponse.json(result);
}Client-Side Usage
// components/WalletWidget.tsx
'use client';
import { fetchMyWallet } from '@codeswayam/api-client';
import { useEffect, useState } from 'react';
import type { UserWalletResponse } from '@codeswayam/api-client';
export function WalletWidget() {
const [wallet, setWallet] = useState<UserWalletResponse | null>(null);
useEffect(() => {
fetchMyWallet().then(setWallet);
}, []);
if (!wallet) return <span>Loading...</span>;
return <span>{wallet.credits.balance} credits</span>;
}Note: For React-based apps, prefer
@codeswayam/accesshooks (useAppAccess,useCSWCredits) over calling@codeswayam/api-clientfunctions directly in components. The hooks provide SWR caching and auto-revalidation.
Error Handling
All functions throw Axios errors on HTTP failures. The response body contains error details:
import { fetchMyEntitlements } from '@codeswayam/api-client';
import axios from 'axios';
async function safeLoad(appId: string) {
try {
return await fetchMyEntitlements(appId);
} catch (error) {
if (axios.isAxiosError(error)) {
const status = error.response?.status;
const message = error.response?.data?.message;
if (status === 401) {
// Token expired or missing — redirect to login
redirectToLogin();
} else if (status === 403) {
// Authenticated but not authorized (e.g. wrong role)
console.error('Access denied:', message);
} else if (status === 402) {
// Insufficient credits
showBuyCreditsModal();
} else {
console.error('API error:', status, message);
}
}
throw error;
}
}Common HTTP status codes:
| Status | Meaning |
|---|---|
| 200 | Success |
| 400 | Bad request (invalid params) |
| 401 | Unauthenticated — token missing or expired |
| 402 | Payment required — insufficient credits |
| 403 | Forbidden — authenticated but not authorized |
| 404 | Resource not found |
| 429 | Rate limited |
| 500 | Internal server error |
Source Structure
packages/api-client/src/
├── index.ts — Barrel exports (all functions and types)
├── client.ts — Axios instance configuration
├── auth.ts — getAuthHeaders(), token utilities
├── sdk.ts — CodeSwayamSDK class
├── functions/
│ ├── auth.ts — getProfile, login, logout, getUsersBatch
│ ├── subscriptions.ts — Subscription CRUD functions
│ ├── credits.ts — Wallet, purchase, usage functions
│ ├── referrals.ts — Referral and coupon functions
│ ├── entitlements.ts — fetchMyEntitlements, trackUsage
│ ├── notifications.ts — Push notification functions
│ └── admin.ts — Admin-only functions
└── types/
├── index.ts — Re-exports all types
├── subscriptions.ts
├── credits.ts
├── entitlements.ts
└── notifications.tsChangelog
v1.3.4
- Added Cross-App Entitlement Grants support (
crossAppGrants: string[]onEntitlementResult) - Extended
EntitlementResultwith granular feature category mapping - Added cross-app capability resolution in
fetchMyEntitlements()andcheckEntitlementAccess()
v1.3.3
- Enhanced SSO ticket verification and session profile hydration
v1.3.1
- Fixed
fetchVapidPublicKeytimeout on slow networks trackUsagenow returns fullTrackUsageResultincludingpercentage
v1.3.0
- Added
getAllAppsEntitlements()for cross-app dashboard use cases - Added
deleteNotificationCampaign() - Added
fetchNotificationStats()with delivery and click rate fields
v1.2.0
- Added
sendNotificationCampaign()for admin push campaigns - Added
fetchNotificationCampaigns() CodeSwayamSDKclass: addedsdk.entitlementsnamespace
v1.1.0
- Added
redeemCouponCode()for promotional codes - Added
createCreditPurchaseOrder()andverifyCreditPurchase()(Razorpay integration) fetchMyWalletnow includesfeatureCostsin the response
v1.0.0 — Initial Release
- Auth functions:
getProfile,login,logout,getUsersBatch - Subscription functions: full CRUD
- Credit functions: wallet, packs, feature costs
- Referral functions: stats and redeem
- Entitlement functions:
fetchMyEntitlements,trackUsage CodeSwayamSDKclass withsdk.authnamespacegetAuthHeaders()utility- Full TypeScript types
Part of the CodeSwayam platform. For support, open an issue in the monorepo.
