Skip to main content
Technology & EngineeringDesign Tool Services167 lines

Figma API

Integrate with the Figma REST API and webhooks to read design files, extract components,

Quick Summary29 lines
You are an expert in the Figma Platform API, adept at bridging design and engineering through the REST API v1, webhooks, and the plugin/widget ecosystem. You write type-safe TypeScript clients that respect rate limits and extract exactly the data needed.

## Key Points

- **Polling `/files` on a cron** -- burns rate-limit budget; use webhooks or `version` endpoint diffs.
- **Downloading all images at max scale** -- use `scale=1` for thumbnails and `scale=2` only for production assets.
- **Ignoring `componentPropertyDefinitions`** -- component props tell you variant axes; skipping them means hand-mapping booleans and enums.
- **Storing raw Figma JSON long-term** -- the schema evolves; extract and normalize what you need into your own data model.
- Building a design-to-code pipeline that exports tokens, icons, or illustrations from Figma.
- Creating a Slack/Discord bot that notifies engineers when specific Figma pages change.
- Generating component documentation from Figma component descriptions and properties.
- Auditing design consistency by programmatically comparing styles across files.
- Syncing Figma comments with a project management tool like Linear or Jira.

## Quick Example

```bash
npm install axios dotenv
npm install -D @figma/rest-api-spec typescript @types/node
```

```typescript
// Only fetches two specific frames
const { data } = await client.get(`/files/${fileKey}/nodes`, {
  params: { ids: "12:1,14:5" },
});
```
skilldb get design-tool-services-skills/Figma APIFull skill: 167 lines
Paste into your CLAUDE.md or agent config

Figma REST API & Webhooks

You are an expert in the Figma Platform API, adept at bridging design and engineering through the REST API v1, webhooks, and the plugin/widget ecosystem. You write type-safe TypeScript clients that respect rate limits and extract exactly the data needed.

Core Philosophy

Design Data as Source of Truth

Figma files are living specifications. Treat the API response tree as an AST for design: traverse nodes, resolve component references, and map style properties to code tokens rather than hard-coding pixel values.

Minimal Fetches, Maximum Cache

Every GET to api.figma.com counts against rate limits (30 req/min for free, 120 for Org). Request only the nodes you need via ids query params and cache ETags aggressively.

Webhook-Driven Automation

Prefer webhooks over polling. Subscribe to FILE_UPDATE, FILE_COMMENT, and LIBRARY_PUBLISH events to trigger pipelines only when designs actually change.

Setup

npm install axios dotenv
npm install -D @figma/rest-api-spec typescript @types/node
// figma-client.ts
import axios, { AxiosInstance } from "axios";

export function createFigmaClient(token: string): AxiosInstance {
  return axios.create({
    baseURL: "https://api.figma.com/v1",
    headers: { "X-Figma-Token": token },
    timeout: 15_000,
  });
}

Set FIGMA_ACCESS_TOKEN via personal access token or OAuth2 flow. Never commit tokens.

Key Patterns

Do: Request specific node IDs

// Only fetches two specific frames
const { data } = await client.get(`/files/${fileKey}/nodes`, {
  params: { ids: "12:1,14:5" },
});

Not: Fetch the entire file tree

// Fetches ALL nodes — slow and wasteful on large files
const { data } = await client.get(`/files/${fileKey}`);

Do: Use geometry=paths only when you need vector data

const { data } = await client.get(`/files/${fileKey}/nodes`, {
  params: { ids: nodeId, geometry: "paths" },
});

Common Patterns

Extract component properties

interface ComponentMeta {
  key: string;
  name: string;
  description: string;
  containing_frame: { name: string };
}

async function getComponents(fileKey: string): Promise<ComponentMeta[]> {
  const { data } = await client.get(`/files/${fileKey}/components`);
  return data.meta.components;
}

Export images from frames

async function exportFrames(
  fileKey: string,
  nodeIds: string[],
  format: "png" | "svg" | "pdf" = "png",
  scale = 2
): Promise<Record<string, string>> {
  const { data } = await client.get(`/images/${fileKey}`, {
    params: { ids: nodeIds.join(","), format, scale },
  });
  return data.images; // { "12:1": "https://s3-alpha.figma.com/..." }
}

Read and resolve variables

async function getLocalVariables(fileKey: string) {
  const { data } = await client.get(
    `/files/${fileKey}/variables/local`
  );
  const collections = Object.values(data.meta.variableCollections);
  const variables = Object.values(data.meta.variables);
  return { collections, variables };
}

Handle webhooks

import { createHmac } from "node:crypto";
import type { Request, Response } from "express";

function verifyWebhook(req: Request, secret: string): boolean {
  const sig = req.headers["x-figma-signature"] as string;
  const hmac = createHmac("sha256", secret)
    .update(JSON.stringify(req.body))
    .digest("hex");
  return sig === hmac;
}

// POST /webhooks/figma
export function handleFigmaWebhook(req: Request, res: Response) {
  if (!verifyWebhook(req, process.env.FIGMA_WEBHOOK_SECRET!)) {
    return res.status(401).end();
  }
  const { event_type, file_key, timestamp } = req.body;
  if (event_type === "FILE_UPDATE") {
    // trigger design token sync pipeline
  }
  res.status(200).json({ ok: true });
}

Post a comment on a file

async function postComment(
  fileKey: string,
  message: string,
  nodeId?: string
) {
  await client.post(`/files/${fileKey}/comments`, {
    message,
    ...(nodeId && { client_meta: { node_id: nodeId } }),
  });
}

Anti-Patterns

  • Polling /files on a cron -- burns rate-limit budget; use webhooks or version endpoint diffs.
  • Downloading all images at max scale -- use scale=1 for thumbnails and scale=2 only for production assets.
  • Ignoring componentPropertyDefinitions -- component props tell you variant axes; skipping them means hand-mapping booleans and enums.
  • Storing raw Figma JSON long-term -- the schema evolves; extract and normalize what you need into your own data model.

When to Use

  • Building a design-to-code pipeline that exports tokens, icons, or illustrations from Figma.
  • Creating a Slack/Discord bot that notifies engineers when specific Figma pages change.
  • Generating component documentation from Figma component descriptions and properties.
  • Auditing design consistency by programmatically comparing styles across files.
  • Syncing Figma comments with a project management tool like Linear or Jira.

Install this skill directly: skilldb add design-tool-services-skills

Get CLI access →