bamboohr-rate-limits
Implement BambooHR rate limiting, backoff, and request optimization. Use when handling 429/503 rate limit errors, implementing retry logic, or optimizing API request throughput for BambooHR. Trigger with phrases like "bamboohr rate limit", "bamboohr throttling", "bamboohr 429", "bamboohr 503", "bamboohr retry", "bamboohr backoff".
What this skill does
# BambooHR Rate Limits
## Overview
BambooHR does not publish exact rate limits, but the API returns `503 Service Unavailable` with a `Retry-After` header when you exceed them. This skill covers detection, backoff, request optimization, and queue-based throttling.
## Prerequisites
- BambooHR API client configured
- Understanding of async/await patterns
## Instructions
### Step 1: Understand BambooHR Rate Limiting Behavior
BambooHR rate limiting details:
| Signal | Value | Description |
|--------|-------|-------------|
| HTTP Status | `503` | Primary rate limit signal |
| `Retry-After` header | seconds (e.g., `30`) | How long to wait before retrying |
| `X-BambooHR-Error-Message` | varies | May contain rate limit detail |
| HTTP Status `429` | rare | Some endpoints return 429 for employee count limits |
**Key insight:** BambooHR uses `503` (not `429`) for rate limiting. Failed authentication attempts also count toward rate limits, so ensure your API key is valid before making many requests.
### Step 2: Implement Retry-After Aware Backoff
```typescript
import { BambooHRApiError } from './client';
interface RetryConfig {
maxRetries: number;
baseDelayMs: number;
maxDelayMs: number;
}
const DEFAULT_RETRY: RetryConfig = {
maxRetries: 5,
baseDelayMs: 1000,
maxDelayMs: 60_000,
};
async function withBambooHRRetry<T>(
operation: () => Promise<T>,
config = DEFAULT_RETRY,
): Promise<T> {
for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
try {
return await operation();
} catch (err) {
if (attempt === config.maxRetries) throw err;
if (!(err instanceof BambooHRApiError)) throw err;
if (!err.retryable) throw err; // Only retry 429, 503, 500, 502
// Honor BambooHR's Retry-After header
let delay: number;
if (err.meta.retryAfter) {
delay = parseInt(err.meta.retryAfter, 10) * 1000;
} else {
// Exponential backoff with jitter
const exponential = config.baseDelayMs * Math.pow(2, attempt);
const jitter = Math.random() * config.baseDelayMs;
delay = Math.min(exponential + jitter, config.maxDelayMs);
}
console.warn(
`BambooHR rate limited (attempt ${attempt + 1}/${config.maxRetries}). ` +
`Waiting ${(delay / 1000).toFixed(1)}s...`
);
await new Promise(r => setTimeout(r, delay));
}
}
throw new Error('unreachable');
}
```
### Step 3: Queue-Based Rate Limiting
```typescript
import PQueue from 'p-queue';
// BambooHR unofficial guidance: stay under ~10 requests/second
const bamboohrQueue = new PQueue({
concurrency: 3, // Max 3 concurrent requests
interval: 1000, // Per 1-second window
intervalCap: 8, // Max 8 requests per second
});
async function rateLimitedRequest<T>(operation: () => Promise<T>): Promise<T> {
return bamboohrQueue.add(() => withBambooHRRetry(operation));
}
// Usage — all requests go through the queue
const employees = await rateLimitedRequest(() => client.getDirectory());
const report = await rateLimitedRequest(() => client.customReport(['firstName', 'lastName']));
// Bulk operations automatically throttled
const employeeDetails = await Promise.all(
employeeIds.map(id =>
rateLimitedRequest(() => client.getEmployee(id, ['firstName', 'lastName', 'jobTitle']))
),
);
```
### Step 4: Reduce Request Volume
**Use custom reports instead of individual GETs:**
```typescript
// BAD: N+1 requests (one per employee)
const employees = await client.getDirectory();
for (const emp of employees.employees) {
const detail = await client.getEmployee(emp.id, ['salary', 'department']);
// 500 employees = 501 requests
}
// GOOD: 1 request using custom report
const report = await client.customReport([
'firstName', 'lastName', 'department', 'jobTitle', 'hireDate',
]);
// 1 request, all employee data
```
**Use incremental sync:**
```typescript
// BAD: Full directory pull every time
const allEmployees = await client.getDirectory();
// GOOD: Only changed employees since last sync
const changed = await client.request<any>(
'GET', `/employees/changed/?since=${lastSyncTimestamp}`,
);
// Only fetch details for employees that actually changed
```
**Use table changed endpoint:**
```typescript
// GET /employees/changed/tables/{tableName}?since=...
const changedJobs = await client.request<any>(
'GET', `/employees/changed/tables/jobInfo?since=${lastSyncTimestamp}`,
);
```
### Step 5: Monitor Rate Limit Usage
```typescript
class BambooHRRateLimitMonitor {
private requestLog: { timestamp: number; status: number }[] = [];
private rateLimitHits = 0;
recordRequest(status: number) {
this.requestLog.push({ timestamp: Date.now(), status });
// Only keep last 5 minutes
const cutoff = Date.now() - 5 * 60 * 1000;
this.requestLog = this.requestLog.filter(r => r.timestamp > cutoff);
if (status === 503 || status === 429) {
this.rateLimitHits++;
}
}
getStats() {
const recent = this.requestLog;
return {
requestsLast5Min: recent.length,
requestsPerSecond: (recent.length / 300).toFixed(2),
rateLimitHits: this.rateLimitHits,
errorRate: recent.filter(r => r.status >= 400).length / Math.max(recent.length, 1),
};
}
shouldBackOff(): boolean {
const stats = this.getStats();
return stats.errorRate > 0.1 || parseFloat(stats.requestsPerSecond) > 8;
}
}
```
## Output
- Retry logic honoring `Retry-After` header
- Queue-based throttling preventing rate limit hits
- Request volume reduction via custom reports and incremental sync
- Rate limit monitoring with stats
## Error Handling
| Signal | Detection | Action |
|--------|-----------|--------|
| `503` + `Retry-After: N` | Check response status + header | Wait N seconds, then retry |
| `503` without `Retry-After` | Status only | Exponential backoff from 1s |
| `429` (employee limit) | Status code | Contact BambooHR to increase limit |
| Many consecutive 503s | Monitor hit count | Pause all requests for 60s |
## Enterprise Considerations
- **Multi-tenant rate limits**: Each company domain has independent rate limits
- **Batch jobs**: Run large syncs during off-peak hours (nights/weekends)
- **Contact BambooHR**: For enterprise-volume needs, request rate limit increases through support
- **Webhook alternatives**: Use webhooks for real-time changes instead of polling (see `bamboohr-webhooks-events`)
## Resources
- [BambooHR API Technical Overview](https://documentation.bamboohr.com/docs/api-details)
- [p-queue Documentation](https://github.com/sindresorhus/p-queue)
## Next Steps
For security configuration, see `bamboohr-security-basics`.
Related in Backend & APIs
jfrog
IncludedInteract with the JFrog Platform via the JFrog CLI and REST/GraphQL APIs. Use this skill when the user wants to manage Artifactory repositories, upload or download artifacts, manage builds, configure permissions, manage users and groups, work with access tokens, configure JFrog CLI servers, search artifacts, manage properties, set up replication, manage JFrog Projects, run security audits or scans, look up CVE details, query exposures scan results from JFrog Advanced Security, manage release bundles and lifecycle operations, aggregate or export platform data, or perform any JFrog Platform administration task. Also use when the user mentions jf, jfrog, artifactory, xray, distribution, evidence, apptrust, onemodel, graphql, workers, mission control, curation, advanced security, exposures, or any JFrog product name.
cupynumeric-migration-readiness
IncludedPre-migration readiness assessor for porting NumPy to cuPyNumeric. Use BEFORE substantial porting work begins when the user asks whether code will scale on GPU, whether they should migrate to cuPyNumeric, which NumPy patterns transfer cleanly, what must be refactored before porting, or mentions pre-port assessment, scaling analysis, or refactor planning. Inspect the user's source code, look up NumPy usage, cross-reference the cuPyNumeric API support manifest, and distinguish distributed-scaling-friendly patterns from blockers such as unsupported APIs, scalar synchronization, host round-trips, Python/object-heavy control flow, shape/data-dependent branching, and in-place mutation hazards. Produce a verdict of READY, LIGHT REFACTOR, SIGNIFICANT REFACTOR, or NOT RECOMMENDED, with concrete refactor pointers.
alibabacloud-data-agent-skill
IncludedInvoke Alibaba Cloud Apsara Data Agent for Analytics via CLI to perform natural language-driven data analysis on enterprise databases. Data Agent for Analytics is an intelligent data analysis agent developed by Alibaba Cloud Database team for enterprise users. It automatically completes requirement analysis, data understanding, analysis insights, and report generation based on natural language descriptions. This tool supports: discovering data resources (instances/databases/tables) managed in DMS, initiating query or deep analysis sessions, real-time progress tracking, and retrieving analysis conclusions and generated reports. Use this Skill when users need to query databases, analyze data trends, generate data reports, ask questions in natural language, or mention "Data Agent", "data analysis", "database query", "SQL analysis", "data insights".
token-optimizer
IncludedReduce OpenClaw token usage and API costs through smart model routing, heartbeat optimization, budget tracking, and native 2026.2.15 features (session pruning, bootstrap size limits, cache TTL alignment). Use when token costs are high, API rate limits are being hit, or hosting multiple agents at scale. The 4 executable scripts (context_optimizer, model_router, heartbeat_optimizer, token_tracker) are local-only — no network requests, no subprocess calls, no system modifications. Reference files (PROVIDERS.md, config-patches.json) document optional multi-provider strategies that require external API keys and network access if you choose to use them. See SECURITY.md for full breakdown.
resend-cli
IncludedUse this skill when the task is specifically about operating Resend from an AI agent, terminal session, or CI job via the official resend CLI: installing/authenticating the CLI, sending/listing/updating/cancelling emails, batch sends, domains and DNS, webhooks and local listeners, inbound receiving, contacts, topics, segments, broadcasts, templates, API keys, profiles, or debugging Resend CLI/API failures. Trigger on mentions of Resend CLI, `resend`, `resend doctor`, `resend emails send`, `resend domains`, `resend webhooks listen`, `resend emails receiving`, or agent-friendly terminal automation.
alibabacloud-odps-maxframe-coding
IncludedUse this skill for MaxFrame SDK development and documentation navigation on Alibaba Cloud MaxCompute (ODPS). Helps answer MaxFrame API, concept, official example, and supported pandas API questions; create data processing programs; read/write MaxCompute tables; debug jobs (remote or local); and build custom DPE runtime images. Trigger when users mention MaxFrame, MaxCompute with MaxFrame, ODPS table processing, DPE runtime, MaxFrame docs/examples, DataFrame/Tensor operations, or GPU runtime setup. Works for both English and Chinese queries about Alibaba Cloud data processing with MaxFrame.