Agent Skills: Clari Rate Limits

|

UncategorizedID: jeremylongshore/claude-code-plugins-plus-skills/clari-rate-limits

Install this agent skill to your local

pnpm dlx add-skill https://github.com/jeremylongshore/claude-code-plugins-plus-skills/tree/HEAD/plugins/saas-packs/clari-pack/skills/clari-rate-limits

Skill Files

Browse the full folder contents for clari-rate-limits.

Download Skill

Loading file tree…

plugins/saas-packs/clari-pack/skills/clari-rate-limits/SKILL.md

Skill Metadata

Name
clari-rate-limits
Description
|

Clari Rate Limits

Overview

The Clari API enforces rate limits per API key. Export jobs are asynchronous and queued server-side, so the primary concern is polling frequency and concurrent export requests.

Rate Limit Behavior

| Aspect | Value | |--------|-------| | Scope | Per API key | | Response on limit | HTTP 429 | | Export job queue | Server-managed, async | | Recommended polling | 5-10 second intervals |

Instructions

Exponential Backoff for Export Polling

import time
import requests

def poll_with_backoff(
    job_id: str,
    api_key: str,
    max_attempts: int = 60,
    base_delay: float = 5.0,
    max_delay: float = 60.0,
) -> dict:
    for attempt in range(max_attempts):
        resp = requests.get(
            f"https://api.clari.com/v4/export/jobs/{job_id}",
            headers={"apikey": api_key},
        )

        if resp.status_code == 429:
            retry_after = int(resp.headers.get("Retry-After", base_delay))
            time.sleep(retry_after)
            continue

        resp.raise_for_status()
        status = resp.json()

        if status["status"] in ("COMPLETED", "FAILED"):
            return status

        delay = min(base_delay * (1.5 ** attempt), max_delay)
        time.sleep(delay)

    raise TimeoutError(f"Job {job_id} did not complete in {max_attempts} attempts")

Sequential Export Scheduler

def export_all_periods(
    client,
    forecast_name: str,
    periods: list[str],
    delay_between: float = 10.0,
) -> list[dict]:
    results = []
    for period in periods:
        print(f"Exporting {period}...")
        job = client.export_forecast(forecast_name, period)
        result = poll_with_backoff(job["jobId"], client.config.api_key)
        results.append(result)
        time.sleep(delay_between)  # Avoid hitting rate limits
    return results

Error Handling

| Scenario | Detection | Response | |----------|-----------|----------| | 429 with Retry-After | Check header | Wait exact duration | | 429 without header | Status code only | Backoff from 5s | | Job queue full | Multiple pending jobs | Wait for completion before new exports |

Resources

Next Steps

For security configuration, see clari-security-basics.