A TypeScript SDK for the ScalePad API with strong typing, Zod v4 validation, pagination helpers, filtering/sorting support, and rate-limit aware retries.
- đź”’ Type-safe: Full TypeScript support with strong typing
- âś… Validated: Zod v4 schema validation for API responses
- 🔄 Pagination: Built-in cursor-based pagination with async generators
- 🔍 Filtering & Sorting: Intuitive API for filtering and sorting resources
- ⚡ Rate Limiting: Automatic retry with exponential backoff and
Retry-Aftersupport - 📝 Logging: Configurable logging with secret redaction
- đź§Ş Well-tested: Comprehensive test coverage
- 📦 Dual Package: ESM and CommonJS support
npm install @scalepad/sdkimport { ScalePadClient } from '@scalepad/sdk';
const client = new ScalePadClient({
apiKey: process.env.SCALEPAD_API_KEY!,
logLevel: 'info',
});
// List clients
const result = await client.core.v1.clients.list({
pageSize: 100,
});
console.log(`Found ${result.total_count} clients`);The SDK requires a ScalePad API key. You can generate one in your ScalePad account:
- Sign into your ScalePad account
- Navigate to your personal API keys
- Select New API key
- Copy the generated API key
For more details, see the Getting Started Guide.
import { ScalePadClient } from '@scalepad/sdk';
const client = new ScalePadClient({
apiKey: 'your-api-key',
// Optional configuration
baseUrl: 'https://api.scalepad.com', // default
timeoutMs: 60000, // default: 60 seconds
logLevel: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'none'
// Retry configuration
retry: {
maxRetries: 3, // default
retryOn429: true, // default
retryOn5xx: true, // default
},
});// List clients
const clients = await client.core.v1.clients.list({
pageSize: 100,
});
// List contacts
const contacts = await client.core.v1.contacts.list();
// List hardware assets
const assets = await client.core.v1.hardwareAssets.list();
// Other resources:
// - client.core.v1.contracts
// - client.core.v1.members
// - client.core.v1.saas
// - client.core.v1.tickets
// - client.core.v1.opportunitiesThe SDK supports all ScalePad API filter operators: eq, in, lt, lte, gt, gte.
// Exact match
const workstations = await client.core.v1.hardwareAssets.list({
filters: {
type: { op: 'eq', value: 'WORKSTATION' },
},
});
// Multiple values (IN operator)
const serverOrWorkstation = await client.core.v1.hardwareAssets.list({
filters: {
type: { op: 'in', value: ['SERVER', 'WORKSTATION'] },
},
});
// Numeric comparison
const lowRamAssets = await client.core.v1.hardwareAssets.list({
filters: {
'configuration.ram_bytes': { op: 'lte', value: 8_000_000_000 },
},
});
// Multiple filters (combined with AND)
const filtered = await client.core.v1.hardwareAssets.list({
filters: {
type: { op: 'eq', value: 'WORKSTATION' },
'configuration.ram_bytes': { op: 'lte', value: 8_000_000_000 },
},
});
// Special characters (automatically quoted)
const client = await client.core.v1.clients.list({
filters: {
name: { op: 'eq', value: 'Space Sprockets, Inc.' },
},
});// Sort by field (ascending by default)
const clients = await client.core.v1.clients.list({
sort: ['name'],
});
// Sort descending
const clients = await client.core.v1.clients.list({
sort: ['-num_hardware_assets'],
});
// Multiple sort fields
const clients = await client.core.v1.clients.list({
sort: ['num_hardware_assets', '-num_contacts'],
});The SDK provides multiple ways to work with paginated results:
let cursor: string | undefined;
let allClients = [];
do {
const result = await client.core.v1.clients.list({
pageSize: 200,
cursor,
});
allClients.push(...result.data);
cursor = result.next_cursor ?? undefined;
} while (cursor);// Iterate through pages
for await (const page of client.core.v1.clients.paginate({ pageSize: 200 })) {
console.log(`Processing ${page.length} clients`);
// Process page...
}// Iterate through individual items
for await (const client of client.core.v1.clients.paginateItems({ pageSize: 200 })) {
console.log(`Processing client: ${client.id}`);
// Process individual client...
}import { collectAll } from '@scalepad/sdk';
// Collect all pages into a single array
const allClients = await collectAll(
(cursor) => client.core.v1.clients.list({ cursor, pageSize: 200 })
);const client = await client.core.v1.clients.getById('client-id');
const contact = await client.core.v1.contacts.getById('contact-id');import {
ScalePadClient,
ApiError,
AuthenticationError,
RateLimitError,
NetworkError,
TimeoutError,
ResponseValidationError,
} from '@scalepad/sdk';
try {
const result = await client.core.v1.clients.list();
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API credentials');
} else if (error instanceof RateLimitError) {
console.error('Rate limited. Retry after:', error.retryAfter);
} else if (error instanceof ApiError) {
console.error('API error:', error.statusCode, error.errors);
} else if (error instanceof NetworkError) {
console.error('Network error:', error.message);
} else if (error instanceof TimeoutError) {
console.error('Request timed out');
} else if (error instanceof ResponseValidationError) {
console.error('Invalid response format:', error.issues);
}
}import { ScalePadClient, Logger } from '@scalepad/sdk';
class CustomLogger implements Logger {
debug(message: string, ...args: unknown[]): void {
// Your custom debug logging
}
info(message: string, ...args: unknown[]): void {
// Your custom info logging
}
warn(message: string, ...args: unknown[]): void {
// Your custom warn logging
}
error(message: string, ...args: unknown[]): void {
// Your custom error logging
}
}
const client = new ScalePadClient({
apiKey: 'your-api-key',
logger: new CustomLogger(),
});The SDK currently supports the following Core API v1 resources (read-only):
- Clients:
client.core.v1.clients - Contacts:
client.core.v1.contacts - Contracts:
client.core.v1.contracts - Hardware Assets:
client.core.v1.hardwareAssets - Members:
client.core.v1.members - SaaS:
client.core.v1.saas - Tickets:
client.core.v1.tickets - Opportunities:
client.core.v1.opportunities
Each resource provides:
list(options?)- List resources with filtering, sorting, and paginationgetById(id)- Get a single resource by IDpaginate(options?)- Async generator for pagespaginateItems(options?)- Async generator for individual items
The SDK automatically handles rate limiting according to the ScalePad API rate limits:
- Default limit: 50 requests per 5 seconds
- On
429 Too Many Requests, the SDK automatically retries after theRetry-Afterduration - Configurable retry behavior via the
retryoption
The SDK is written in TypeScript and provides full type definitions:
import type {
Client,
Contact,
Contract,
HardwareAsset,
Member,
SaaS,
Ticket,
Opportunity,
Filters,
SortSpec,
ListResult,
PaginatedResponse,
} from '@scalepad/sdk';# Install dependencies
npm install
# Build
npm run build
# Run tests
npm test
# Type check
npm run typecheck
# Lint
npm run lintSee the examples directory for complete usage examples:
- quickstart.ts - Basic usage and common patterns
For full API documentation, visit:
- Node.js >= 18 (for native
fetchsupport) - TypeScript >= 5.0 (if using TypeScript)
MIT
Contributions are welcome! Please feel free to submit a Pull Request.
For issues and questions: