界面已本地化;技能介绍与说明文档按所选语言由 AI 自动翻译,代码、命令、路径和专业术语保留原文,以原作者文档为准。
探索技能
效率与协作 · SKILL.md

figma-cost-tuning

figma-cost-tuning

【效率与协作】Optimize Figma API usage to minimize costs and stay within plan limits. Use when analyzing request volumes, reducing unnecessary API calls, or choosing the right Figma plan for your integration needs. Trigger with phrases like "figma cost", "figma pricing", "reduce figma API calls", "figma plan limits", "figma budget".

独立 GitHub 快照 · 自动分类 · 以原作者文档为准

技能说明

GitHub

name: figma-cost-tuning description: 'Optimize Figma API usage to minimize costs and stay within plan limits.

Use when analyzing request volumes, reducing unnecessary API calls,

or choosing the right Figma plan for your integration needs.

Trigger with phrases like "figma cost", "figma pricing",

"reduce figma API calls", "figma plan limits", "figma budget".

' allowed-tools: Read, Grep version: 1.6.0 license: MIT author: Jeremy Longshore jeremy@intentsolutions.io tags:

  • saas
  • figma compatibility: Designed for Claude Code

Figma Cost Tuning

Overview

Optimize Figma API usage costs. Figma's REST API rate limits are determined by plan tier and seat type. Reducing unnecessary requests keeps you within limits and avoids upgrading prematurely.

Prerequisites

  • Working Figma integration with request logging
  • Understanding of your current API call volume
  • Access to Figma admin settings (for plan details)

Instructions

Step 1: Understand Plan-Based Rate Limits

Figma rate limits vary by plan tier and seat type:

PlanSeat TypesRate Limit TierVariables API
Starter (Free)FreeLowestNo
ProfessionalFull, ViewerStandardNo
OrganizationFull, Collab, ViewerHigherNo
EnterpriseFull, Collab, ViewerHighestYes

Key facts:

  • Rate limits are per-user, per-minute
  • View and Collab seats have lower limits than Full seats
  • The Variables API (/v1/files/:key/variables/*) requires Enterprise
  • Endpoint tiers (1/2/3) have different quotas within each plan

Step 2: Track API Usage

// Instrument all Figma API calls to track volume
class FigmaUsageTracker {
  private calls: Array<{ endpoint: string; timestamp: number; cached: boolean }> = [];

  record(endpoint: string, cached: boolean) {
    this.calls.push({ endpoint, timestamp: Date.now(), cached });
  }

  getReport(windowMs = 24 * 60 * 60 * 1000) {
    const cutoff = Date.now() - windowMs;
    const recent = this.calls.filter(c => c.timestamp > cutoff);

    // Group by endpoint
    const byEndpoint = new Map<string, { total: number; cached: number }>();
    for (const call of recent) {
      const key = call.endpoint.replace(/[a-zA-Z0-9]{20,}/, ':key');
      const entry = byEndpoint.get(key) || { total: 0, cached: 0 };
      entry.total++;
      if (call.cached) entry.cached++;
      byEndpoint.set(key, entry);
    }

    return {
      totalCalls: recent.length,
      cachedCalls: recent.filter(c => c.cached).length,
      cacheHitRate: recent.length > 0
        ? (recent.filter(c => c.cached).length / recent.length * 100).toFixed(1) + '%'
        : '0%',
      byEndpoint: Object.fromEntries(byEndpoint),
    };
  }
}

const tracker = new FigmaUsageTracker();

Step 3: Reduce API Calls

// 1. Use depth parameter to avoid fetching full file trees
// Saves bandwidth and processing time
const fileMeta = await figmaFetch(`/v1/files/${key}?depth=1`);

// 2. Batch node IDs into single requests
// Instead of 50 individual /nodes calls, make 1 call with 50 IDs
const ids = nodeIds.join(',');
await figmaFetch(`/v1/files/${key}/nodes?ids=${ids}`);

// 3. Cache with webhooks instead of polling
// Polling every 30s = 2,880 calls/day per file
// Webhooks = 0 polling calls (events push to you)

// 4. Cache image URLs (they're valid for 30 days)
// Re-rendering the same nodes wastes Tier 1 quota

// 5. Use GET /v1/files/:key?depth=1 to check lastModified
// before fetching the full file (skip if unchanged)
async function fetchFileIfChanged(
  fileKey: string,
  lastKnownVersion: string,
  token: string
) {
  const meta = await fetch(
    `https://api.figma.com/v1/files/${fileKey}?depth=1`,
    { headers: { 'X-Figma-Token': token } }
  ).then(r => r.json());

  if (meta.version === lastKnownVersion) {
    console.log('File unchanged, skipping full fetch');
    return null;
  }

  // File changed -- fetch the full version
  return fetch(
    `https://api.figma.com/v1/files/${fileKey}`,
    { headers: { 'X-Figma-Token': token } }
  ).then(r => r.json());
}

Step 4: Cost-Saving Architecture

Polling Architecture (expensive):
  App → GET /v1/files/:key every 30s → 2,880 calls/day/file

Webhook Architecture (efficient):
  Figma → POST /webhooks/figma (only when file changes)
  App → GET /v1/files/:key (only after webhook) → ~10-50 calls/day/file

Savings: 95%+ fewer API calls

Step 5: Usage Dashboard Query

// Log API calls to a database for analysis
interface ApiCallLog {
  timestamp: Date;
  endpoint: string;
  fileKey: string;
  status: number;
  latencyMs: number;
  cached: boolean;
}

// Monthly usage summary
function getMonthlyReport(logs: ApiCallLog[]) {
  const now = new Date();
  const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
  const monthLogs = logs.filter(l => l.timestamp >= monthStart);

  return {
    totalRequests: monthLogs.length,
    uniqueFiles: new Set(monthLogs.map(l => l.fileKey)).size,
    cacheHitRate: monthLogs.filter(l => l.cached).length / monthLogs.length,
    errorRate: monthLogs.filter(l => l.status >= 400).length / monthLogs.length,
    topEndpoints: Object.entries(
      monthLogs.reduce((acc, l) => {
        acc[l.endpoint] = (acc[l.endpoint] || 0) + 1;
        return acc;
      }, {} as Record<string, number>)
    ).sort(([,a], [,b]) => b - a).slice(0, 5),
  };
}

Output

  • API usage tracked by endpoint and file
  • Unnecessary calls eliminated with caching and webhooks
  • Bandwidth reduced with depth parameter
  • Monthly usage reports for capacity planning

Error Handling

IssueCauseSolution
Hitting rate limits oftenNo caching or batchingImplement caching + batch requests
Variables API 403Not on Enterprise planUse styles API (free on all plans)
High bandwidth costsFetching full file treesUse depth=1 and /nodes endpoint
Polling wasteNo webhooks configuredSet up FILE_UPDATE webhook

Examples

Find your most expensive call pattern with the Step 2 usage tracker, then apply the Step 3 fix:

Top API consumers (last 24h)
  /v1/files/{key}          1,847 calls   ← full-tree fetches from the preview service
  /v1/files/{key}/nodes      312 calls
  /v1/images/{key}           119 calls
# Before: full tree (~4 MB, counts hard against the budget)
curl -s -H "X-Figma-Token: ${FIGMA_PAT}" "https://api.figma.com/v1/files/${FIGMA_FILE_KEY}"

# After: shallow fetch (~40 KB) — same top-level structure the preview needs
curl -s -H "X-Figma-Token: ${FIGMA_PAT}" "https://api.figma.com/v1/files/${FIGMA_FILE_KEY}?depth=1"

That single change cut the daily call payload ~99% for the hot path. Plan-tier limits and the dashboard query: references/understand-plan-based-rate-limits.md, references/usage-dashboard-query.md.

Resources

Next Steps

For architecture patterns, see figma-reference-architecture.

我的收藏