Salesloft sdk patterns
'Apply production-ready SalesLoft API patterns for TypeScript and Python.From its SKILL.md
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill salesloft-sdk-patternsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
5.2 KB, ~1.2k tokens by cl100k_base, as published. Nobody here has run it
SalesLoft SDK Patterns
Overview
Production-ready patterns for the SalesLoft REST API v2. There is no official TypeScript/Python SDK -- build a typed wrapper around https://api.salesloft.com/v2/ with automatic pagination, retry, and error normalization.
Prerequisites
- Completed
salesloft-install-authsetup axiosornode-fetchinstalled- Familiarity with async/await and generics
Instructions
Step 1: Typed API Client Singleton
// src/salesloft/client.ts
import axios, { AxiosInstance, AxiosError } from 'axios';
interface SalesloftPaging {
per_page: number;
current_page: number;
total_pages: number;
total_count: number;
}
interface SalesloftListResponse<T> {
data: T[];
metadata: { paging: SalesloftPaging };
}
interface SalesloftSingleResponse<T> {
data: T;
}
let instance: AxiosInstance | null = null;
export function getSalesloftClient(): AxiosInstance {
if (!instance) {
instance = axios.create({
baseURL: process.env.SALESLOFT_BASE_URL || 'https://api.salesloft.com/v2',
headers: { Authorization: `Bearer ${process.env.SALESLOFT_API_KEY}` },
timeout: 30_000,
});
// Add response interceptor for rate-limit headers
instance.interceptors.response.use(undefined, handleRateLimitError);
}
return instance;
}
Step 2: Automatic Pagination Iterator
// SalesLoft paginates with page/per_page params, max 100 per page
async function* paginate<T>(
endpoint: string,
params: Record<string, any> = {},
): AsyncGenerator<T> {
const client = getSalesloftClient();
let page = 1;
let totalPages = 1;
do {
const { data: response } = await client.get<SalesloftListResponse<T>>(
endpoint, { params: { ...params, per_page: 100, page } }
);
for (const item of response.data) yield item;
totalPages = response.metadata.paging.total_pages;
page++;
} while (page <= totalPages);
}
// Usage: iterate all people
for await (const person of paginate<Person>('/people.json')) {
console.log(person.display_name);
}
Step 3: Error Handling with Rate-Limit Awareness
// SalesLoft uses cost-based rate limiting: 600 cost/min
// High-page requests (page > 100) cost 3-30 points instead of 1
async function handleRateLimitError(error: AxiosError) {
if (error.response?.status === 429) {
const retryAfter = parseInt(
error.response.headers['retry-after'] || '60', 10
);
console.warn(`Rate limited. Waiting ${retryAfter}s...`);
await new Promise(r => setTimeout(r, retryAfter * 1000));
return getSalesloftClient().request(error.config!);
}
throw error;
}
class SalesloftApiError extends Error {
constructor(
message: string,
public status: number,
public retryable: boolean,
) {
super(message);
this.name = 'SalesloftApiError';
}
}
Step 4: Python Equivalent
import os, time, requests
from typing import Iterator, Any
class SalesloftClient:
BASE_URL = "https://api.salesloft.com/v2"
def __init__(self, api_key: str | None = None):
self.session = requests.Session()
self.session.headers["Authorization"] = f"Bearer {api_key or os.environ['SALESLOFT_API_KEY']}"
def get(self, endpoint: str, **params) -> dict:
resp = self.session.get(f"{self.BASE_URL}/{endpoint}", params=params)
if resp.status_code == 429:
time.sleep(int(resp.headers.get("Retry-After", 60)))
return self.get(endpoint, **params)
resp.raise_for_status()
return resp.json()
def paginate(self, endpoint: str, **params) -> Iterator[dict]:
page = 1
while True:
result = self.get(endpoint, page=page, per_page=100, **params)
yield from result["data"]
if page >= result["metadata"]["paging"]["total_pages"]:
break
page += 1
Output
- Type-safe client singleton with rate-limit retry
- Automatic pagination that handles all pages
- Error normalization for consistent handling
- Python and TypeScript implementations
Error Handling
| Status | Meaning | Retryable | Cost |
|---|---|---|---|
401 | Invalid/expired token | No (refresh token) | 0 |
404 | Resource not found | No | 1 |
422 | Validation error | No (fix payload) | 1 |
429 | Rate limited | Yes (wait Retry-After) | 0 |
5xx | Server error | Yes (backoff) | 1 |
Resources
Next Steps
Apply patterns in salesloft-core-workflow-a for real-world usage.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.