Salesloft rate limits
'Handle SalesLoft cost-based rate limiting with backoff and request budgeting.From its SKILL.md
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill salesloft-rate-limitsAssembled 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
4.4 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
SalesLoft Rate Limits
Overview
SalesLoft uses cost-based rate limiting at 600 cost per minute. Each request costs 1 point by default, but deep pagination multiplies the cost. Rate limit state is returned in response headers.
Rate Limit Model
Cost per Request
| Page Range | Cost per Request | Example: 1000 records at 100/page |
|---|---|---|
| 1-100 | 1 point | Pages 1-10: 10 points |
| 101-150 | 3 points | N/A for this example |
| 151-250 | 8 points | N/A |
| 251-500 | 10 points | N/A |
| 501+ | 30 points | N/A |
Budget: 600 points/minute. A simple 10-page pagination costs 10 points. But paginating to page 500 costs 10 + 150 + 800 + 2500 = 3460 points (nearly 6 minutes of budget).
Response Headers
X-RateLimit-Limit-Per-Minute: 600
X-RateLimit-Remaining-Per-Minute: 487
Retry-After: 42 # Only present on 429 responses
X-Request-Id: abc-123 # For support tickets
Instructions
Step 1: Rate-Limit-Aware Client
import axios, { AxiosInstance } from 'axios';
class SalesloftRateLimiter {
private remaining = 600;
private resetAt = Date.now();
constructor(private client: AxiosInstance) {
client.interceptors.response.use(
(res) => {
this.remaining = parseInt(res.headers['x-ratelimit-remaining-per-minute'] || '600');
return res;
},
async (err) => {
if (err.response?.status === 429) {
const wait = parseInt(err.response.headers['retry-after'] || '60');
console.warn(`Rate limited. Waiting ${wait}s (X-Request-Id: ${err.response.headers['x-request-id']})`);
await this.sleep(wait * 1000);
return this.client.request(err.config);
}
throw err;
}
);
}
async throttledRequest<T>(fn: () => Promise<T>): Promise<T> {
if (this.remaining < 10) {
const waitMs = Math.max(0, this.resetAt - Date.now());
if (waitMs > 0) await this.sleep(waitMs);
}
return fn();
}
private sleep(ms: number) { return new Promise(r => setTimeout(r, ms)); }
}
Step 2: Pagination Cost Calculator
function paginationCost(totalRecords: number, perPage: number = 100): number {
const totalPages = Math.ceil(totalRecords / perPage);
let cost = 0;
for (let p = 1; p <= totalPages; p++) {
if (p <= 100) cost += 1;
else if (p <= 150) cost += 3;
else if (p <= 250) cost += 8;
else if (p <= 500) cost += 10;
else cost += 30;
}
return cost;
}
// Budget check before large exports
const totalPeople = 25000; // from metadata.paging.total_count
const cost = paginationCost(totalPeople);
const minutes = Math.ceil(cost / 600);
console.log(`Export will cost ${cost} points (~${minutes} minutes at rate limit)`);
Step 3: Queue-Based Throttling for Bulk Operations
import PQueue from 'p-queue';
// Max 5 concurrent, 10 per second (600/min = 10/sec)
const queue = new PQueue({ concurrency: 5, interval: 1000, intervalCap: 10 });
async function bulkCreatePeople(people: any[]) {
const results = await Promise.allSettled(
people.map(person =>
queue.add(() => api.post('/people.json', person))
)
);
const succeeded = results.filter(r => r.status === 'fulfilled').length;
console.log(`Created ${succeeded}/${people.length} people`);
}
Error Handling
| Scenario | Cost Impact | Strategy |
|---|---|---|
| Simple list (page 1-10) | 10 points | No throttle needed |
| Full export (250 pages) | 910 points | ~2 min, add delays |
| Bulk create (500 records) | 500 points | Queue with intervalCap |
| Deep pagination (page 500) | 3460 points | Cache or use webhooks instead |
Resources
Next Steps
For security configuration, see salesloft-security-basics.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.