Figma
Build from your designs.
Connect Figma with a token, then paste a Figma link in a prompt ("build the pricing section from this design: https://www.figma.com/design/…?node-id=42-1337"); the agent reads that frame. In Figma, right-click a frame → Copy link to selection for a link to exactly that frame. Tokens are stored encrypted and never returned.
Create a token: Figma → Settings → Security → Personal access tokens → Generate new token, with the scopes current_user:read and file_content:read (it starts with figd_). An Organization or Enterprise plan access token works the same way and survives people leaving the team.
#Connect Figma
/api/v1/vcaas/projects/:projectId/figma/connectapi-keyFreeLink a Figma account to the project. The token is checked with Figma before anything is stored. Launch Project also takes figma.token.
Path parameters
| Parameter | Type | Description |
|---|---|---|
projectId | string | The project id |
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Figma personal or plan access token |
Response fields
| Field | Type | Description |
|---|---|---|
data.connected | boolean | true |
data.account | object | { id, handle, email?, imgUrl? } of the Figma account |
Example request
curl -X POST \
-H "api-key: tlm_sk_your_key" \
-H "Content-Type: application/json" \
-d '{"token":"figd_xxx"}' \
https://builder-api.totalum.app/api/v1/vcaas/projects/barber-bookings/figma/connectconst res = await fetch("https://builder-api.totalum.app/api/v1/vcaas/projects/barber-bookings/figma/connect", {
method: "POST",
headers: {
"api-key": process.env.TOTALUM_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"token": "figd_xxx"
}),
});
const { errors, data } = await res.json();{ "errors": null, "data": { "connected": true, "account": { "id": "123456", "handle": "Ada Lovelace", "email": "ada@example.com", "imgUrl": "https://s3-alpha.figma.com/profile/…" } } }Error codes
| Code | HTTP | Meaning |
|---|---|---|
MISSING_FIGMA_TOKEN | 400 | token is missing |
FIGMA_TOKEN_MALFORMED | 400 | Not a Figma token (whitespace, a URL, too short) |
FIGMA_TOKEN_INVALID | 400 | Figma rejected it: wrong, expired or revoked |
FIGMA_TOKEN_FORBIDDEN | 400 | Missing the current_user:read / file_content:read scopes |
FIGMA_RATE_LIMITED | 400 | Figma is rate-limiting; retry shortly |
FIGMA_UNREACHABLE | 400 | Figma could not be reached |
AGENT_RUNNING | 409 | A prompt is running |
#Check a Figma Token
/api/v1/vcaas/figma/validateapi-keyFreeCheck a token without connecting it — for a connect form. 10 checks a minute per account.
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
token | string | Yes | The token |
Response fields
| Field | Type | Description |
|---|---|---|
data.valid | boolean | true |
data.account | object | { id, handle, email?, imgUrl? } |
Example request
curl -X POST \
-H "api-key: tlm_sk_your_key" \
-H "Content-Type: application/json" \
-d '{"token":"figd_xxx"}' \
https://builder-api.totalum.app/api/v1/vcaas/figma/validateconst res = await fetch("https://builder-api.totalum.app/api/v1/vcaas/figma/validate", {
method: "POST",
headers: {
"api-key": process.env.TOTALUM_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"token": "figd_xxx"
}),
});
const { errors, data } = await res.json();{ "errors": null, "data": { "valid": true, "account": { "id": "123456", "handle": "Ada Lovelace", "email": "ada@example.com" } } }Error codes
| Code | HTTP | Meaning |
|---|---|---|
FIGMA_TOKEN_MISSING | 400 | No token |
FIGMA_TOKEN_MALFORMED / FIGMA_TOKEN_INVALID / FIGMA_TOKEN_FORBIDDEN / FIGMA_RATE_LIMITED / FIGMA_UNREACHABLE | 400 | As in Connect Figma |
RATE_LIMITED | 429 | More than 10 checks a minute |
#Get Figma Status
/api/v1/vcaas/projects/:projectId/figma/statusapi-keyFreeWhether Figma is connected, and to which account. A failed re-check never disconnects it.
Path parameters
| Parameter | Type | Description |
|---|---|---|
projectId | string | The project id |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
verify | boolean | No | true re-checks the token with Figma (a live call: on screen open, not in a poll) |
Response fields
| Field | Type | Description |
|---|---|---|
data.connected | boolean | Connected |
data.account | object | undefined | { id, handle, email?, imgUrl? } |
data.connectedAt | string | undefined | When it was connected |
data.tokenValid | boolean | undefined | With verify=true: Figma still accepts the token |
data.tokenError | string | undefined | With verify=true: why it failed |
data.expiresAt | string | undefined | Token expiry, when known |
Example request
curl -H "api-key: tlm_sk_your_key" \
"https://builder-api.totalum.app/api/v1/vcaas/projects/barber-bookings/figma/status?verify=true"const res = await fetch("https://builder-api.totalum.app/api/v1/vcaas/projects/barber-bookings/figma/status?verify=true", {
headers: {
"api-key": process.env.TOTALUM_API_KEY,
},
});
const { errors, data } = await res.json();{ "errors": null, "data": { "connected": true, "account": { "id": "123456", "handle": "Ada Lovelace" }, "connectedAt": "2026-10-08T10:24:00.000Z", "tokenValid": true } }#Disconnect Figma
/api/v1/vcaas/projects/:projectId/figma/connectapi-keyFreeRemove the Figma connection (nothing changes in your Figma account). Calling it on a project that is not connected also answers 200.
Path parameters
| Parameter | Type | Description |
|---|---|---|
projectId | string | The project id |
Response fields
| Field | Type | Description |
|---|---|---|
data.disconnected | boolean | true |
data.message | string | Confirmation |
Example request
curl -X DELETE -H "api-key: tlm_sk_your_key" \
https://builder-api.totalum.app/api/v1/vcaas/projects/barber-bookings/figma/connectconst res = await fetch("https://builder-api.totalum.app/api/v1/vcaas/projects/barber-bookings/figma/connect", {
method: "DELETE",
headers: {
"api-key": process.env.TOTALUM_API_KEY,
},
});
const { errors, data } = await res.json();{ "errors": null, "data": { "disconnected": true, "message": "Figma disconnected successfully" } }