About Figma
Figma is a collaborative interface-design platform for design files, prototyping, and design systems. Serval connects to Figma in one of two ways: with a Figma OAuth app that you own (recommended), where Serval refreshes the access token itself so nothing expires, or with a personal access token that you paste in and rotate by hand. Either way the connection acts as the Figma user who authorized it, limited by the scopes granted, and Serval only ever sends credentials to one host: api.figma.com.
Authentication: Your own Figma OAuth app (authorization code with automatic refresh), or a personal access token (API key).
Data sync: On-demand only. There is no background sync, resource import, or scheduled polling - Serval calls Figma only when a workflow or health check runs.
What the Figma integration enables
Anything defined in the Figma API can be accessed through Serval.
Get your credentials
Figma limits personal access tokens to 90 days. An OAuth app that you own gives Serval a refresh token instead, so the connection renews itself. Do this once, signed in to Figma as a team admin with a Full or Dev seat - the connection acts as that user, and Figma throttles View seats to a handful of API calls per month. Many teams use a shared IT account here so the connection survives staff changes.Create the app and copy its credentials
Open Figma developer apps and create a new app with your team as the owner. Figma shows the Client ID and Client secret once, right after creation: copy both into your password manager now. Register Serval's callback URL
Open the Figma connect dialog in Serval, choose Connect with your Figma OAuth app, and copy the Callback URL it shows. Paste it into the app’s OAuth 2.0 redirect URLs. Figma requires an exact match, so copy it rather than retyping it.
Select scopes and publish
In the app’s configuration flow, on the OAuth scopes page, select every scope you plan to request in Serval, then publish the app as Private. Serval always requests current_user:read (it names the connection and powers the health check); the defaults also cover file contents, metadata, versions, comments, dev resources, folders (Figma’s new name for projects), libraries, and webhooks. Leave the Enterprise-only scopes (variables, library analytics, and the org scopes) off unless your plan includes them - Figma rejects them at consent otherwise. Scopes you add later take effect only after you publish the app again.
Check the published version
Private apps serve your own team without a Figma review. Don’t leave the app in Draft: a Draft app can’t call the REST API, and a published version without the scopes you selected fails at consent with “Invalid scopes for app”.
A personal access token carries the access of the Figma user who creates it, narrowed by the scopes chosen at creation, and Figma caps its lifetime at 90 days. Figma’s guide: Manage personal access tokens.Open the token settings
In Figma, open Settings, then the Security tab, then Personal access tokens.
Create the token
Generate a token named for Serval, grant the scopes your workflows need, and pick the longest expiration Figma offers. Note the date: when it lapses, workflows fail until you paste a new token (or switch the connection to an OAuth app).
Copy the token immediately
Figma shows the token only once.
Connect in Serval
Add a new Figma connection from your Serval integrations page. The connect dialog offers two options.
- Copy the Callback URL into your Figma app if you haven’t already.
- Enter an optional Display name (defaults to
Figma (<email>) with the authorizing user’s email), the Client ID, and the Client secret.
- Tick the scopes Serval may request.
current_user:read is always included. Every selected scope must also be enabled on your Figma app.
- Click Connect Figma and approve the request on Figma’s consent screen. You have 10 minutes from clicking Connect; after that the attempt fails with “Invalid or expired OAuth state” and you resubmit.
On success Serval stores the tokens encrypted and refreshes the access token automatically before it expires.Enter an optional Instance Name and the Personal Access Token, then click Connect. Serval stores the token encrypted and sends it as X-Figma-Token on every call.
Switching an existing token connection to the OAuth app: open the connection and click Reconnect, then choose Connect with your Figma OAuth app. The connection is converted in place - its roles, policies, and workflow bindings stay - and the old token is discarded. The reverse isn’t offered: an OAuth-app connection can’t be switched back to a token without deleting it.
When you reconnect an OAuth-app connection, the Display name, Client ID, and scopes are pre-filled from the existing setup. The Client secret is never stored where the dialog can read it, so re-enter it (or regenerate it in Figma if it’s lost).
Verifying the connection
Figma connections include the built-in health check Test Figma Connection, which asks Figma which user the connection acts as. It runs automatically when you connect and can be run again from the connection’s page; when Health Alerts are enabled it also runs on the daily schedule.
- Success:
Successfully connected to Figma as "<email or handle>".
- Failure:
Unable to connect to Figma. The access token may have expired or been revoked, or the OAuth app may have been unpublished; reconnect the integration.
A passing check proves the credential is valid. If a workflow still fails on a specific file, project, or team, the authorizing Figma user can’t see that resource, or the call needs a scope or Figma plan the connection doesn’t have.
Gotchas and troubleshooting
Figma keeps one access token per app per user
Every time a user authorizes your Figma app, or Serval refreshes the token, Figma invalidates that user’s previous access token for the same app. Connect Figma once per authorizing user per Figma app; if a second Serval team needs its own connection, create a second Figma app or authorize with a different account. Never point a staging or test environment at the app a production connection uses.
Which account should authorize the app
The connection acts as the authorizing user and inherits that user’s seat. Team webhooks require a team admin, and Figma limits View seats and other non-editor seats to a few file reads per month, so authorize as a team admin with a Full or Dev seat. If that person leaves the team, the tokens stop working and the connection must be reconnected by someone else.
Consent fails or the callback is rejected
Three causes cover almost every case: the Callback URL registered on the Figma app doesn’t match Serval’s exactly (copy it from the dialog), a selected scope isn’t enabled on the published version of the app (Figma answers “Invalid scopes for app” and scope changes only take effect after you publish the app again), or the app is still in Draft. Figma’s authorization codes also expire 30 seconds after issue, so finish the consent screen promptly.
Public Figma apps behave differently
Serval expects a Private app. Figma blocks Public apps from the team projects and project files endpoints and puts them through a review queue, so publishing the app as Public removes “Browse teams and projects” from the connection.
Workflows suddenly fail with an authentication error
For a token connection, the token has expired (90-day cap) or was revoked: reconnect with a new token, or switch to an OAuth app. For an OAuth-app connection, the app was unpublished, its secret rotated, or the authorizing user lost access: reconnect. Serval passes Figma’s error text through where it has one.
Variables, activity logs, library analytics, or payments calls fail while file reads work
These areas are gated by Figma, not Serval: variables need Enterprise, activity logs need an organization admin on Enterprise, payments only cover plugins, widgets, and Community files you own. Nothing on the Serval side changes this.
Calls fail because of a bad file key
Figma identifies files by a file key, the string right after “file/” or “design/” in the file’s web address, not the full URL. Node, team, and project IDs are separate values.
Token connections: the Instance name doubles as the connection's identity
For access-token connections Serval derives an internal identifier from the Instance name once, at creation. Two token connections on the same team with the same name (or both left blank) resolve to the same connection, so give each a distinct name; leaving the name blank when rotating a token keeps the existing one. OAuth-app connections are keyed on the authorizing Figma user instead.
Rate limits look far lower than expected
Figma tracks limits per authorizing user, per app, and per the plan of the file being read. Files kept in drafts or a free space get Starter limits with multi-day retry windows; keep the files your workflows touch inside the paid team.
Need help? Contact support@serval.com for assistance with your Figma integration.