Claude-code-plugins lucidchart-rate-limits

install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/lucidchart-pack/skills/lucidchart-rate-limits" ~/.claude/skills/jeremylongshore-claude-code-plugins-lucidchart-rate-limits && rm -rf "$T"
manifest: plugins/saas-packs/lucidchart-pack/skills/lucidchart-rate-limits/SKILL.md
source content

Lucidchart Rate Limits

Overview

Lucidchart's API enforces per-OAuth-token rate limits, with document mutation operations (creating shapes, updating pages, modifying text) throttled more aggressively than read-only document listing. Automations that programmatically generate architecture diagrams or org charts from external data sources can easily exceed write limits when placing dozens of shapes and connectors in a single batch. Image export endpoints carry additional latency due to server-side rendering, making export-heavy workflows the most common throttling bottleneck.

Rate Limit Reference

EndpointLimitWindowScope
List documents120 req1 minutePer OAuth token
Get document / pages60 req1 minutePer OAuth token
Create/update shapes30 req1 minutePer OAuth token
Export to PNG/PDF10 req1 minutePer OAuth token
Create document15 req1 minutePer OAuth token

Rate Limiter Implementation

class LucidRateLimiter {
  private tokens: number;
  private lastRefill: number;
  private readonly max: number;
  private readonly refillRate: number;
  private queue: Array<{ resolve: () => void }> = [];

  constructor(maxPerMinute: number) {
    this.max = maxPerMinute;
    this.tokens = maxPerMinute;
    this.lastRefill = Date.now();
    this.refillRate = maxPerMinute / 60_000;
  }

  async acquire(): Promise<void> {
    this.refill();
    if (this.tokens >= 1) { this.tokens -= 1; return; }
    return new Promise(resolve => this.queue.push({ resolve }));
  }

  private refill() {
    const now = Date.now();
    this.tokens = Math.min(this.max, this.tokens + (now - this.lastRefill) * this.refillRate);
    this.lastRefill = now;
    while (this.tokens >= 1 && this.queue.length) {
      this.tokens -= 1;
      this.queue.shift()!.resolve();
    }
  }
}

const writeLimiter = new LucidRateLimiter(25);
const exportLimiter = new LucidRateLimiter(8);

Retry Strategy

async function lucidRetry<T>(
  limiter: LucidRateLimiter, fn: () => Promise<Response>, maxRetries = 3
): Promise<T> {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    await limiter.acquire();
    const res = await fn();
    if (res.ok) return res.json();
    if (res.status === 429) {
      const retryAfter = parseInt(res.headers.get("Retry-After") || "20", 10);
      const jitter = Math.random() * 2000;
      await new Promise(r => setTimeout(r, retryAfter * 1000 + jitter));
      continue;
    }
    if (res.status >= 500 && attempt < maxRetries) {
      await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 2000));
      continue;
    }
    throw new Error(`Lucidchart API ${res.status}: ${await res.text()}`);
  }
  throw new Error("Max retries exceeded");
}

Batch Processing

async function batchCreateShapes(docId: string, pageId: string, shapes: any[], batchSize = 5) {
  const results: any[] = [];
  for (let i = 0; i < shapes.length; i += batchSize) {
    const batch = shapes.slice(i, i + batchSize);
    const batchResults = await Promise.all(
      batch.map(shape => lucidRetry(writeLimiter, () =>
        fetch(`${LUCID_BASE}/documents/${docId}/pages/${pageId}/shapes`, {
          method: "POST", headers,
          body: JSON.stringify(shape),
        })
      ))
    );
    results.push(...batchResults);
    if (i + batchSize < shapes.length) await new Promise(r => setTimeout(r, 8000));
  }
  return results;
}

Error Handling

IssueCauseFix
429 on shape creationExceeded 30 writes/min token limitBatch shapes, space 3s apart
429 on PNG exportExport limit (10/min) is very lowQueue exports with 8s spacing
408 on large documentExport rendering timeoutRequest single page, not full doc
401 token expiredOAuth token TTL exceededRefresh token before batch operations
409 concurrent editAnother user editing same pageRetry after 5s with fresh page version

Resources

Next Steps

See

lucidchart-performance-tuning
.