Connect Figma (Authorize)
Method
This API follows the REST methodology.
HTTP Method
POST: Mint the Figma consent URL an organization admin opens to connect the Figma OAuth app โ the credential the wf2des scheduler runs on.
This is a deliberate one-time setup action, not part of plugin login. See Why this exists.
Naming Convention
To ensure consistency and readability, JSON nodes in requests and responses use camelCase.
Request and Response
Headers
Request Headers
AuthorizationAcceptAccept-language
Response Headers
Content-Type
Authorize
URI
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| organization_id | integer | Required | Organization ID |
Request Body
None.
Response
The response is JSON (HTTP status: 200 OK).
{
"authorizeUrl": "https://www.figma.com/oauth?client_id=โฆ&redirect_uri=โฆ&scope=file_content%3Aread&state=โฆ&response_type=code",
"expiresInSeconds": 600
}
Response Fields
| Name | Type | Description |
|---|---|---|
| authorizeUrl | string | The Figma consent URL. Carries a signed, expiring, organization-bound state. |
| expiresInSeconds | integer | How long the link stays usable (600). After that, request a new one. |
Open it signed in as the SERVICE ACCOUNT
Open authorizeUrl in a private/incognito window signed in as the dedicated Figma service account โ not your own Figma user. A browser already signed in as the admin binds the grant to that person, which looks like success and reintroduces exactly the dependency this replaces: the scheduler then breaks when they rotate access or leave.
The service account must have access to the Figma files
An OAuth grant carries only what the authorizing account can already see. If the service
account has not been invited to the team or files the project uses, every Figma read returns
403 Request denied โ the grant itself is valid, so this looks like a broken integration
rather than a permissions gap.
Verified in practice: on the same file and the same request, a PAT belonging to an account with
access returned 200, while a freshly-issued grant for an account without access returned
403. Invite the service account to the files (or their team) before connecting, and
confirm afterwards with a file read.
Authentication
JWT issued by the Admin Cognito pool, plus organization-level read/write access. This establishes an organization-wide credential, so a regular application user or project owner cannot replace it.
Error Handling
| Description | Status Code | Status Name |
|---|---|---|
| Missing authentication credentials | 401 | Unauthorized |
| Admin role lacks organization read/write access | 403 | Forbidden |
| Organization does not exist | 404 | Not Found |
| Figma OAuth is not configured on this deployment | 500 | Internal Server Error |
The 500 names which of FIGMA_OAUTH_CLIENT_ID / FIGMA_OAUTH_CLIENT_SECRET / FIGMA_OAUTH_REDIRECT_URI / FIGMA_OAUTH_STATE_SECRET is missing โ all four are required together.
Processing Flow
- Extract the organization ID from path parameters.
- Verify the Admin Cognito session and organization read/write access.
- Mint
stateโ a signed, org-bound, 10-minute token (see callback for why it matters). - Build the Figma consent URL with
client_id, the registeredredirect_uri,scope=file_content:read,state,response_type=code. - Return the URL. Nothing is stored yet.
Why this exists
The scheduled component_sweep is a bodyless EventBridge invoke โ no user, no request, no tenancy beyond the default organization. A personal access token cannot serve it: it is one human's standing authority with no expiry we control, and the worker holds no PostgreSQL client to reach the platform figma_token table at all.
Figma supports only the authorization-code flow โ there is no client-credentials / machine-to-machine grant โ so a headless run can never mint its own credential. Exactly one human step is unavoidable, and this endpoint is it. Everything afterwards is an automatic refresh in the Admin API. The worker requests only a valid access token from the Admin API.
The client secret alone is not enough: it identifies the app, not the authority to read anyone's files.