executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
hootsuite-rate-limitsImplement Hootsuite rate limiting, backoff, and idempotency patterns. Use when handling rate limit errors, implementing retry logic, or optimizing API request throughput for Hootsuite. Trigger with phrases like "hootsuite rate limit", "hootsuite throttling", "hootsuite 429", "hootsuite retry", "hootsuite backoff".
Independent GitHub snapshot · Automated classification · Original documentation governs
name: hootsuite-rate-limits description: 'Implement Hootsuite rate limiting, backoff, and idempotency patterns.
Use when handling rate limit errors, implementing retry logic,
or optimizing API request throughput for Hootsuite.
Trigger with phrases like "hootsuite rate limit", "hootsuite throttling",
"hootsuite 429", "hootsuite retry", "hootsuite backoff".
' allowed-tools: Read, Write, Edit version: 1.6.0 license: MIT author: Jeremy Longshore jeremy@intentsolutions.io tags:
Handle Hootsuite API rate limits. The API returns 429 Too Many Requests with Retry-After headers when limits are exceeded.
| Endpoint | Limit | Window |
|---|---|---|
| General API | Varies by plan | Per minute |
| Message scheduling | ~100/hour | Per hour |
| Media upload | ~50/hour | Per hour |
| Token refresh | ~10/hour | Per hour |
async function rateLimitedRequest(url: string, options: RequestInit = {}) {
const response = await fetch(url, {
...options,
headers: { 'Authorization': `Bearer ${process.env.HOOTSUITE_ACCESS_TOKEN}`, ...options.headers },
});
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
console.log(`Rate limited. Retrying in ${retryAfter}s`);
await new Promise(r => setTimeout(r, retryAfter * 1000));
return rateLimitedRequest(url, options); // Retry
}
return response;
}
import PQueue from 'p-queue';
const hootsuiteQueue = new PQueue({
concurrency: 1,
interval: 1000,
intervalCap: 2, // 2 requests per second
});
async function queuedSchedule(profileId: string, text: string, time: Date) {
return hootsuiteQueue.add(() =>
fetch('https://platform.hootsuite.com/v1/messages', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.HOOTSUITE_ACCESS_TOKEN}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ text, socialProfileIds: [profileId], scheduledSendTime: time.toISOString() }),
})
);
}
Return a rate-limit receipt with account scope, requested/limited/deferred counts, retry revision, idempotency state, queue health, draft/public assertion, and rollback reference. Exclude copy, media, handles, and credentials.
Stop for unknown profile, quota saturation, an attempt to replay a public mutation, or a public-post path during recovery. Defer or cancel work rather than bypassing approval or account scope.
scope=sandbox-brand; requested=100; limited=3; deferred=3; retry=v2; idempotent=pass; public_posts=0; rollback=limits-r7 proves bounded handling.
For security, see hootsuite-security-basics.