Baserow Figma Integration - Sync Design Tokens and Activity
There is no built-in button that syncs Baserow and Figma directly, but the open-source edition can still bridge the two: a script reads rows from a Baserow table and pushes them into Figma Variables through the REST API, while in the other direction Figma webhooks - comments, library publishes, status changes - post events into a Baserow automation that creates a row for each one; neither direction needs a plugin, and both keep working even when nobody has the file open.
How It Works
Design and data usually live in separate tools: designers work in Figma, while product data, copy, and task status live in Baserow. The traditional bridge is a plugin, but a plugin depends on a designer remembering to open it and click “Sync.” Calling the Figma REST API directly works differently - it does not care whether the file is open, and it can run on a schedule or in response to an event.
There are two independent architecture patterns:
- Variables sync (Baserow → Figma): design token values (colors, copy, numbers) live in Baserow and get pushed to Figma Variables via the REST API on a schedule.
- Activity log (Figma → Baserow): Figma webhooks log comments and file updates straight into a Baserow table for a single project overview.
This is more resilient than a plugin: the script talks to Figma’s server directly and keeps working even if no one has the file open.
Pattern A: Variables Sync (Baserow → Figma)
Instead of a designer typing hex codes or copy by hand, design layers get bound to Figma Variables, and Baserow acts as the database backing their values. When marketing updates a price or a tagline in Baserow, a script pushes that change straight into Figma.
Use Cases
- Localization: text strings for different languages live in Baserow columns.
- Theming: color tokens for light mode and dark mode.
- Product data: live pricing or inventory numbers that show up in design mockups.
Step 1: Prerequisites
- Figma personal access token. From the Figma file browser, open the account menu in the top-left corner, go to Settings → Security, and click Generate new token under Personal access tokens.
- Baserow database (API) token. See Baserow database (API) tokens for how to create one and what permissions it needs. Never hand these tokens to anyone you do not want accessing your data.
- Figma file key. The alphanumeric value in the design file’s URL, sitting between the file type and the file name - for example
figma.com/{file_type}/{file_key}/{file_name}.
The Figma token is passed in the X-Figma-Token header on every API request.
Step 2: The Bridge Script
Figma’s API is passive - it never sends data on its own, so an external runner (a GitHub Action or a plain cron script) has to do two things:
GETdata from Baserow - for example, a “Brand Assets” table - via the Baserow REST API .POSTthe updates to Figma’s/v1/files/:file_key/variablesendpoint, which bulk-creates, updates, and deletes variables and variable collections.
import requests
# Configuration
BASEROW_API_URL = "https://api.baserow.io/api/database/rows/table/YOUR_TABLE_ID/"
FIGMA_API_URL = "https://api.figma.com/v1/files/YOUR_FILE_KEY/variables"
HEADERS_BASEROW = {"Authorization": "Token YOUR_BASEROW_TOKEN"}
HEADERS_FIGMA = {"X-Figma-Token": "YOUR_FIGMA_TOKEN", "Content-Type": "application/json"}
def sync_design_tokens():
# 1. Fetch "Single Source of Truth" from Baserow
response = requests.get(BASEROW_API_URL, headers=HEADERS_BASEROW, params={"user_field_names": "true"})
data = response.json()
# Initialize the list to hold all our value updates
value_updates = []
# 2. Iterate through rows and prepare Figma updates
for row in data['results']:
variable_id = row['Figma Variable ID'] # e.g., "VariableID:123"
mode_id = row['Figma Mode ID'] # e.g., "1:0" (Required by Figma)
new_value = row['Value'] # e.g., "Welcome Home"
# 3. Append to our update list using Figma's required schema
value_updates.append({
"variableId": variable_id,
"modeId": mode_id,
"value": new_value
})
# 4. Construct the final payload and push to Figma
payload = {
"variableModeValues": value_updates
}
# 5. Make the atomic POST request
response = requests.post(FIGMA_API_URL, headers=HEADERS_FIGMA, json=payload)
if response.status_code == 200:
print(f"Successfully updated {len(value_updates)} variable values!")
else:
print(f"Failed to update variables. Error: {response.status_code}")
print(response.json())
sync_design_tokens()Figma expects specific data types - strings, numbers, or RGBA objects. The script acts as the translator between how a value is stored in Baserow and the format Figma expects.
Pattern B: Project Tracking (Figma → Baserow)
When the goal is to track the design process itself rather than its content, use Figma webhooks: they let you observe events in a file - a collaborator leaving a comment, or a new version appearing in the file’s history - and turn Baserow into a live activity feed for the design team.
Creating a webhook is a Tier 2 operation, so the Figma personal access token must be issued with the webhooks:write scope.
Use Cases
- Design QA: a new comment on a file automatically creates a task in Baserow.
- Version control: a library publish logs the version history in Baserow.
Figma Event Types
| Event Type | Best Use Case | Key Data Sent to Baserow |
|---|---|---|
FILE_COMMENT | Design QA: capture designer feedback and turn it into actionable tasks | comment text, @mentions, and timestamp |
DEV_MODE_STATUS_UPDATE | Handoff tracking: know exactly when a frame is ready for dev | node ID, status (READY_FOR_DEV), and change message |
LIBRARY_PUBLISH | Version control: log when a design system component is updated | list of created/modified components and variables |
Step 1: Set Up the Baserow Automation
- Create a “Design Log” table in Baserow.
- Create an automation with the “Receive an HTTP request (webhook)” trigger.
- Copy the webhook URL.
For more on how the trigger itself receives requests, see Webhooks in Baserow .
Step 2: Create the Figma Webhook
The listener is registered with a POST request - from a terminal or a tool like Postman. By default, Figma immediately sends a PING event to the endpoint, confirming the webhook is live and will receive updates.
curl -X POST https://api.figma.com/v2/webhooks \
-H "X-Figma-Token: YOUR_PERSONAL_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"event_type": "FILE_COMMENT",
"context": "file",
"context_id": "YOUR_FILE_KEY",
"endpoint": "YOUR_BASEROW_WEBHOOK_URL",
"passcode": "my_secure_secret",
"status": "ACTIVE",
"description": "Sync Figma comments to Baserow Task Log"
}'To track every file in a project or team, change context to project or team and pass the matching ID instead of a file key.
Always set a passcode: Figma includes this string in every request it sends, and the Baserow side can check it to confirm a payload genuinely came from Figma rather than an unrelated source.
Step 3: Map the Figma Payload to a Baserow Row
When a designer leaves a comment, Figma sends a fairly large JSON payload. The Create Row action needs to map specific fields:
triggered_by.handle→ the “Assignee” field.comment[0].text→ the “Task Description” field.https://www.figma.com/file/YOUR_FILE_KEY?node-id=...→ the “URL” field.
Troubleshooting Common Issues
- 401 Unauthorized: the database token needs Write permission when Figma is the side pushing data in, and the header value must be prefixed with the word
Token. - The 30-minute rule: the
FILE_UPDATEevent only fires after 30 minutes of inactivity in the file - useFILE_COMMENTfor instant logging instead. - Delivery verification: the
GET /v2/webhooks/:webhook_id/requestsendpoint shows a log of every attempt Figma made to reach your webhook. - Color formatting: Figma variables expect color as a decimal RGBA object (for example,
{"r": 1, "g": 0.5, "b": 0, "a": 1}) rather than a hex code - make sure Baserow values match that shape.
Frequently Asked Questions
Do both patterns need to be set up together? No - variables sync and activity logging are independent. Enable only the design-token push, only the Figma event log, or both, depending on the team’s needs.
Does this integration require a Figma plugin? No - both patterns work directly through the Figma REST API and webhooks, with no plugin to install and no manual step to open a file and trigger a sync.
How do I get an instant reaction to a file change instead of waiting up to 30 minutes? Use the FILE_COMMENT event instead of FILE_UPDATE - it fires right after the designer’s action rather than after a period of inactivity in the file.
Related reading: the Baserow REST API overview for direct table calls without webhooks, and the Tally integration as another example of accepting external data through a webhook automation trigger.