Connectors
/
Figma
Live · 44 tools

Figma Integration for AI Agents

The Figma REST API is well-documented. Getting your agent to call it correctly — for real users, with OAuth apps published and scopes that match exactly — is the part that takes longer than it should.
Figma
Live

Design

Collaboration

Status
Live
Tools
44 pre-built
Auth
OAuth 2.0
Credential storage
Sandbox support

OAuth 2.0

Auto token refresh

Revocation detection

BYOC required

The real problem

Why this is harder than it looks

Figma's REST API is clean and the authentication docs are thorough. Most developers expect to have a working prototype in a few hours. The friction starts when you move from a personal test token to an OAuth app acting on behalf of real users.

The first thing to understand: Figma's OAuth app publishing model has three distinct states — draft, private, and public. A draft app can only be tested by you and admins in your associated team or organization. It cannot authorize any other user. To let your customers connect their Figma accounts, you must publish the app — either as private (accessible to your org only, no review required) or public (accessible to all Figma users, requires Figma's review and approval process). If you're building a B2B SaaS product, you'll need private or public — and you cannot skip this step. Many developers only discover this after building out the entire integration and wondering why users outside the org get blocked.

Then there's token lifecycle. Figma OAuth access tokens expire after 90 days. Figma maintains only one active access token per OAuth app per user — when you refresh, the previous token is immediately invalidated. If any part of your system holds a reference to the old token, those calls will silently fail with a 403. You need refresh logic that updates the stored token atomically, before anything else tries to use it.

Scope selection is another friction point. Figma's scopes are granular and must be declared in your app's configuration before users authorize. The scopes requested at authorization time must be a subset of what you declared — a mismatch blocks the install with an error users can't self-resolve. Variables and webhooks require dedicated scopes beyond files:read. Enterprise-only endpoints (activity logs, library analytics) require both an Enterprise plan and separate scopes that won't be relevant for most users — requesting them unnecessarily raises concerns at the consent screen.

Scalekit handles app credential storage, token refresh, revocation detection, and per-user isolation. Your agent names a tool and passes parameters. The OAuth plumbing is not your problem.

Capabilities

What your agent can do with Figma

Once connected, your agent has 44 pre-built tools covering the full Figma API surface:

  • Read and inspect files: fetch the complete document tree, specific nodes by ID, image renders (PNG, JPG, SVG, PDF), image fills, and version history
  • Manage comments and reactions: list, create, and delete comments; add and remove emoji reactions on comment threads
  • Explore design systems: list and retrieve published components, component sets, and styles at the file or team level
  • Read and write variables: access local and published variable collections; create, update, or delete variables and modes (requires file_variables:read / file_variables:write)
  • Navigate teams and projects: get team metadata, list projects, and enumerate files within a project
  • Manage dev resources and webhooks: create, update, and delete dev resource links on nodes; register and manage team webhooks for file events
Setup context

What we're building

This guide connects a design assistant agent to Figma — helping designers and developers inspect files, manage comments, track design system components, and automate handoff workflows without leaving your product.

🤖
Example agent
Design assistant reading Figma files, surfacing comments, and inspecting components on behalf of each user
🔐
Auth model
B2B SaaS — each user connects their own Figma account. identifier = your user ID
⚙️
Scalekit account
app.scalekit.com — Client ID, Secret, Env URL
🔑
Figma OAuth app
Register at figma.com/developers/apps — required for BYOC setup
Setup

1 Setup: One SDK, One credential

Install the Scalekit SDK. The only credential your application manages is the Scalekit API key — no Figma secrets, no user tokens, nothing belonging to your users.

pip install scalekit-sdk-python
npm install @scalekit-sdk/node
import scalekit.client import os from dotenv import load_dotenv load_dotenv() scalekit = scalekit.client.ScalekitClient( client_id=os.getenv("SCALEKIT_CLIENT_ID"), client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), env_url=os.getenv("SCALEKIT_ENV_URL"), ) actions = scalekit.actions
import { ScalekitClient } from '@scalekit-sdk/node'; import 'dotenv/config'; const scalekit = new ScalekitClient( process.env.SCALEKIT_ENV_URL, process.env.SCALEKIT_CLIENT_ID, process.env.SCALEKIT_CLIENT_SECRET ); const actions = scalekit.actions;
Already have credentials?
Connected Accounts

2 Per-User Auth: Creating connected accounts

Each user gets their own Connected Account, giving them a dedicated auth context. The identifier is any unique string from your system — a UUID, email, whatever you use internally.

response = actions.get_or_create_connected_account( connection_name="figma", identifier="user_figma_456" # your internal user ID ) connected_account = response.connected_account print(f"Status: {connected_account.status}") # Status: PENDING — user hasn't authorized yet
const response = await actions.getOrCreateConnectedAccount({ connectionName: "figma", identifier: "user_figma_456" // your internal user ID }); const connectedAccount = response.connectedAccount; console.log(`Status: ${connectedAccount.status}`); // Status: PENDING — user hasn't authorized yet

This call is idempotent — safe to call on every session start. Returns the existing account if one already exists.

Authorization Flow

3 The authorization flow

The user authorizes your agent once. Scalekit generates the OAuth URL with correct scopes, PKCE challenge, and redirect handling pre-configured. After approval, you never see the token.

if connected_account.status != "ACTIVE": link = actions.get_authorization_link( connection_name="figma", identifier="user_figma_456" ) # Redirect user → Figma's native OAuth consent screen # Scalekit captures the token on callback return redirect(link.link)
if (connectedAccount.status !== "ACTIVE") { const { link } = await actions.getAuthorizationLink({ connectionName: "figma", identifier: "user_figma_456" }); // Redirect user → Figma's native OAuth consent screen // Scalekit captures the token on callback return redirect(link); }
Token management is automatic
After the user approves, Scalekit stores encrypted tokens and the connected account moves to ACTIVE. Figma access tokens expire after 90 days — Scalekit refreshes them proactively before expiry. Since Figma invalidates the previous token on each refresh, Scalekit updates the stored token atomically. If a user revokes access from their Figma account settings, the account moves to REVOKED — no silent failures. Check account.status before critical operations.
BYOC is required for Figma
Scalekit does not provide a managed Figma OAuth app. You must register your own app at figma.com/developers/apps, publish it (private or public), paste the Scalekit redirect URI as the callback URL, then enter your Client ID and Client Secret in the Scalekit dashboard. Token management is fully handled after that one-time setup.
Calling Figma

4 Calling Figma: What your agent writes

With the connected account active, your agent calls Figma actions using execute_tool. Name the tool, pass parameters. Scalekit handles token retrieval, request construction, and response parsing.

Get the authenticated user

Confirm who authorized the connection. Useful at session start to resolve the user's identity before making file-level calls.

result = actions.execute_tool( identifier="user_figma_456", tool_name="figma_me_get", tool_input={} ) # Returns: { "id": "...", "email": "...", "handle": "...", "img_url": "..." }
const result = await actions.executeTool({ identifier: "user_figma_456", toolName: "figma_me_get", toolInput: {} }); // Returns: { id, email, handle, img_url }

Fetch a file's document tree

Retrieve the full node tree for a Figma file. The file_key is the alphanumeric string in the file's URL. Use depth to limit how deep into the tree the response goes — large files can return substantial payloads without it.

result = actions.execute_tool( identifier="user_figma_456", tool_name="figma_file_get", tool_input={ "file_key": "hbmVKqA1LGjTuU3HfNLq7p", "depth": 2 } ) # Returns full document tree with pages, frames, and component metadata
const result = await actions.executeTool({ identifier: "user_figma_456", toolName: "figma_file_get", toolInput: { "file_key": "hbmVKqA1LGjTuU3HfNLq7p", "depth": 2 } }); // Returns full document tree with pages, frames, and component metadata

Render nodes as images

Export specific nodes as PNG, JPG, SVG, or PDF. Returns signed download URLs. Scale between 0.01 and 4 — use 2 for retina-quality exports.

result = actions.execute_tool( identifier="user_figma_456", tool_name="figma_file_images_render", tool_input={ "file_key": "hbmVKqA1LGjTuU3HfNLq7p", "ids": "1:2,1:3", "format": "png", "scale": 2 } ) # Returns: { "images": { "1:2": "https://...", "1:3": "https://..." } }
const result = await actions.executeTool({ identifier: "user_figma_456", toolName: "figma_file_images_render", toolInput: { "file_key": "hbmVKqA1LGjTuU3HfNLq7p", "ids": "1:2,1:3", "format": "png", "scale": 2 } }); // Returns: { images: { "1:2": "https://...", "1:3": "https://..." } }

Post a comment on a file

Create a comment at a specific canvas position or anchored to a node. Use comment_id to reply to an existing thread.

result = actions.execute_tool( identifier="user_figma_456", tool_name="figma_file_comment_create", tool_input={ "file_key": "hbmVKqA1LGjTuU3HfNLq7p", "message": "Spacing here should match the design system token — see Spacing/400", "client_meta": { "node_id": "1:2", "node_offset": { "x": 0, "y": 0 } } } ) # Returns: { "id": "...", "message": "...", "created_at": "..." }
const result = await actions.executeTool({ identifier: "user_figma_456", toolName: "figma_file_comment_create", toolInput: { "file_key": "hbmVKqA1LGjTuU3HfNLq7p", "message": "Spacing here should match the design system token — see Spacing/400", "client_meta": { node_id: "1:2", node_offset: { x: 0, y: 0 } } } }); // Returns: { id, message, created_at }
Framework wiring

5 Wiring into your agent framework

Scalekit integrates directly with LangChain. The agent decides what to call; Scalekit handles auth on every invocation. No token plumbing in your agent logic.

from langchain_anthropic import ChatAnthropic from langchain.agents import AgentExecutor, create_tool_calling_agent from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from scalekit.langchain import get_tools figma_tools = get_tools( connection_name="figma", identifier="user_figma_456" ) prompt = ChatPromptTemplate.from_messages([ ("system", "You are a design assistant. Use the available tools to help inspect Figma files, manage comments, and surface design system components."), MessagesPlaceholder("chat_history", optional=True), ("human", "{input}"), MessagesPlaceholder("agent_scratchpad"), ]) agent = create_tool_calling_agent(ChatAnthropic(model="claude-sonnet-4-6"), figma_tools, prompt) result = AgentExecutor(agent=agent, tools=figma_tools).invoke({ "input": "List all open comments on this file and summarize the feedback by frame" })
import { ChatAnthropic } from "@langchain/anthropic"; import { AgentExecutor, createToolCallingAgent } from "langchain/agents"; import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts"; import { getTools } from "@scalekit-sdk/langchain"; const figmaTools = getTools({ connectionName: "figma", identifier: "user_figma_456" }); const prompt = ChatPromptTemplate.fromMessages([ ["system", "You are a design assistant. Use the available tools to help inspect Figma files, manage comments, and surface design system components."], new MessagesPlaceholder("chat_history", true), ["human", "{input}"], new MessagesPlaceholder("agent_scratchpad"), ]); const agent = await createToolCallingAgent({ llm: new ChatAnthropic({ model: "claude-sonnet-4-6" }), tools: figmaTools, prompt }); const result = await AgentExecutor.fromAgentAndTools({ agent, tools: figmaTools }).invoke({ input: "List all open comments on this file and summarize the feedback by frame" });
Other frameworks supported
Tool reference

All 44 Figma tools

Grouped by capability. Your agent calls tools by name — no API wrappers to write.

Files & Nodes
figma_file_get
Retrieve a file's full document tree with depth, node ID, geometry, and plugin data filters
figma_file_nodes_get
Fetch specific nodes from a file by comma-separated node IDs, with depth and geometry options
figma_file_images_render
Render nodes as PNG, JPG, SVG, or PDF at a specified scale; returns signed download URLs
figma_file_image_fills_get
Return download URLs for all image fills applied to nodes in a file
figma_file_versions_list
List a file's version history with IDs, labels, descriptions, and timestamps; cursor-paginated
Comments & Reactions
figma_file_comments_list
List all comments on a file including text, author, position, and resolved status
figma_file_comment_create
Post a new comment at a canvas position or anchored to a node; supports thread replies via comment_id
figma_file_comment_delete
Delete a comment by ID; only the comment author or file owner can delete
figma_comment_reactions_list
List emoji reactions on a specific comment; cursor-paginated
figma_comment_reaction_create
Add an emoji reaction to a comment (e.g. :+1:, :heart:)
figma_comment_reaction_delete
Remove the authenticated user's emoji reaction from a comment
Components & Styles
figma_file_components_list
List all published components in a file with keys, names, descriptions, and thumbnails
figma_component_get
Retrieve metadata for a single published component by its key
figma_file_component_sets_list
List all published component sets (variant groups) in a file
figma_component_set_get
Retrieve metadata for a single published component set by its key
figma_team_components_list
List all published components across a team's shared library; paginated
figma_team_component_sets_list
List all published component sets across a team's shared library; paginated
figma_file_styles_list
List all published styles (color, text, effect, grid) in a file
figma_style_get
Retrieve metadata for a published style by its key
figma_team_styles_list
List all published styles across a team's shared library; paginated
Variables
figma_file_variables_local_get
Return all local variables and variable collections in a file. Requires file_variables:read scope
figma_file_variables_published_get
Return published variables and variable collections from a file's library. Requires file_variables:read scope
figma_file_variables_update
Create, update, or delete variables, variable modes, and collections in a file. Requires file_variables:write scope
Teams & Projects
figma_me_get
Return the authenticated user's profile — name, email, handle, and profile image URL
figma_team_get
Return metadata about a Figma team including name and member count
figma_team_projects_list
List all projects within a team accessible to the authenticated user
figma_project_files_list
List all files in a project with keys, names, thumbnails, and last-modified timestamps
Dev Resources
figma_dev_resources_list
List dev resource links (Storybook, Jira, docs, etc.) attached to nodes in a file; filter by node ID
figma_dev_resource_create
Attach an external URL to a node with a display name — visible in Figma Dev Mode
figma_dev_resource_update
Update an existing dev resource's name or URL by dev resource ID
figma_dev_resource_delete
Permanently remove a dev resource from a node
Webhooks
figma_webhook_create
Register a webhook for team events (FILE_UPDATE, FILE_VERSION_UPDATE, LIBRARY_PUBLISH, FILE_COMMENT, etc.) with a passcode for payload verification. Requires webhooks:write scope
figma_webhook_get
Retrieve a webhook's event type, endpoint, and status by ID
figma_webhook_update
Update a webhook's endpoint, passcode, status (ACTIVE / PAUSED), or description
figma_webhook_delete
Permanently delete a webhook, stopping all future event deliveries
figma_team_webhooks_list
List all webhooks registered for a team
figma_webhook_requests_list
View delivery history for a webhook — payloads, response codes, and timestamps
Payments & Enterprise
figma_payments_get
Return payment and plan information for a user, community file, or plugin
figma_activity_logs_list
List organization activity log events filtered by type and time range. Enterprise plan + org admin required
figma_library_analytics_component_actions_get
Analytics on component insert, detach, and usage actions from a library file. Enterprise only
figma_library_analytics_component_usages_get
Snapshot of how many times each component from a library is used across the org. Enterprise only
figma_library_analytics_style_actions_get
Analytics on style insertion and detachment actions from a library file. Enterprise only
figma_library_analytics_style_usages_get
Snapshot of style usage counts across the org. Enterprise only
figma_library_analytics_variable_actions_get
Analytics on variable actions from a library file. Enterprise only
figma_library_analytics_variable_usages_get
Snapshot of variable usage counts across the org. Enterprise only
Connector notes

Figma-specific behavior

OAuth apps must be published before users outside your org can connect
A draft Figma OAuth app can only be authorized by you and admins in your associated team or organization. To let customers connect, you must publish the app — either privately (your org only, no review required) or publicly (requires Figma review). Build this step into your release checklist; it's easy to miss in development and surfaces as a blocking error for users at authorization time.
Figma invalidates the previous token on every refresh
Figma maintains only one active access token per OAuth app per user. When a token is refreshed, the previous token stops working immediately. Scalekit handles this atomically — the stored token is updated before any agent call proceeds. If you're building your own refresh logic outside Scalekit, ensure writes are atomic or you'll see 403s from the stale token.
file_key and node IDs are different identifiers
The file_key is the alphanumeric string in the Figma file URL (e.g. figma.com/file/hbmVKqA1.../...). Node IDs are the numeric identifiers for individual layers within a file (e.g. "1:2"). These are separate — tools that operate on specific nodes require both the file_key and the node IDs. Use figma_file_get to discover node IDs before making targeted calls.
Enterprise tools require an Enterprise plan and additional scopes
Activity logs (figma_activity_logs_list) and all library analytics tools require a Figma Enterprise plan and organization admin permissions. Requesting enterprise scopes for non-Enterprise users will not cause errors at authorization, but the API calls will return 403s at runtime. Only request these scopes if your agent actually uses them.
Infrastructure decision

Why not build this yourself

The Figma OAuth flow is documented. Token storage isn't technically hard. But here's what you're actually signing up for:

PROBLEM 01
Figma's OAuth app publishing model — draft, private, public — means users outside your org are blocked until you publish. Public apps require Figma's review. Missing this step blocks your launch
PROBLEM 02
Figma invalidates the previous access token on every refresh — non-atomic token storage causes 403s for any code path still holding the old token
PROBLEM 03
Scope selection declared at app configuration must match authorization requests exactly — a mismatch silently blocks installs with errors users cannot self-resolve
PROBLEM 04
Per-user token isolation across a multi-tenant system — one user's Figma credentials must never be accessible to another, even within the same organization

That's one connector. Your agent product will eventually need GitHub, Salesforce, Slack, Notion, and whatever else your customers ask for. Each has its own OAuth quirks and failure modes.

Scalekit maintains every connector. You maintain none of them.

Ready to ship

Connect your agent to Figma today

Free to start. Bring your own Figma OAuth app. Token management fully handled.
Figma
Live

Design

Collaboration

Status
Live
Tools
44 pre-built
Auth
OAuth 2.0
Credential storage
Sandbox support