curl --request POST \
--url https://api.dittowords.com/v2/textItems/linkFigmaNodes \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"projectId": "project-id-1",
"textItemId": "greeting",
"figma": {
"nodeIds": [
"1:23",
"1:24"
],
"branchId": null
}
}
'import requests
url = "https://api.dittowords.com/v2/textItems/linkFigmaNodes"
payload = {
"projectId": "project-id-1",
"textItemId": "greeting",
"figma": {
"nodeIds": ["1:23", "1:24"],
"branchId": None
}
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
projectId: 'project-id-1',
textItemId: 'greeting',
figma: {nodeIds: ['1:23', '1:24'], branchId: null}
})
};
fetch('https://api.dittowords.com/v2/textItems/linkFigmaNodes', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.dittowords.com/v2/textItems/linkFigmaNodes",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'projectId' => 'project-id-1',
'textItemId' => 'greeting',
'figma' => [
'nodeIds' => [
'1:23',
'1:24'
],
'branchId' => null
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.dittowords.com/v2/textItems/linkFigmaNodes"
payload := strings.NewReader("{\n \"projectId\": \"project-id-1\",\n \"textItemId\": \"greeting\",\n \"figma\": {\n \"nodeIds\": [\n \"1:23\",\n \"1:24\"\n ],\n \"branchId\": null\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.dittowords.com/v2/textItems/linkFigmaNodes")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"projectId\": \"project-id-1\",\n \"textItemId\": \"greeting\",\n \"figma\": {\n \"nodeIds\": [\n \"1:23\",\n \"1:24\"\n ],\n \"branchId\": null\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.dittowords.com/v2/textItems/linkFigmaNodes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"projectId\": \"project-id-1\",\n \"textItemId\": \"greeting\",\n \"figma\": {\n \"nodeIds\": [\n \"1:23\",\n \"1:24\"\n ],\n \"branchId\": null\n }\n}"
response = http.request(request)
puts response.read_body{
"projectId": "project-id-1",
"textItemId": "greeting",
"branchId": null,
"results": [
{
"figmaNodeId": "1:23",
"outcome": "linked",
"linkedTextItemId": "greeting"
},
{
"figmaNodeId": "1:24",
"outcome": "not_found",
"message": "This Figma text node is not in the cache for the target project context. Sync first, then retry."
}
]
}{
"message": "Project \"project-id-1\" is not linked to Figma."
}{
"message": "Text item \"greeting\" was not found in project \"project-id-1\"."
}Link Figma nodes to a text item
Links one or more Figma text nodes to an existing text item in a Figma-linked project, so those nodes become Figma instances of that text item.
The nodes must already have been synced to Ditto through the Ditto Figma plugin. Pass figma.branchId to link nodes inside a branch file; without it, nodes are looked up in the project’s main Figma file.
The link is recorded in Ditto right away, but Ditto writes to a Figma file only from the plugin. So the Figma layer doesn’t reflect the link — and later edits to the text item don’t reach that layer — until someone next opens the Ditto Figma plugin on the file.
Nodes are handled independently rather than all-or-nothing: the response reports an outcome per node ID — linked, already_linked, not_found (sync the file from the plugin, then retry), not_text_node, wrong_file_or_branch, or main_component_text_node (link instance text nodes directly, or link the main component’s text from the Figma plugin).
curl --request POST \
--url https://api.dittowords.com/v2/textItems/linkFigmaNodes \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"projectId": "project-id-1",
"textItemId": "greeting",
"figma": {
"nodeIds": [
"1:23",
"1:24"
],
"branchId": null
}
}
'import requests
url = "https://api.dittowords.com/v2/textItems/linkFigmaNodes"
payload = {
"projectId": "project-id-1",
"textItemId": "greeting",
"figma": {
"nodeIds": ["1:23", "1:24"],
"branchId": None
}
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
projectId: 'project-id-1',
textItemId: 'greeting',
figma: {nodeIds: ['1:23', '1:24'], branchId: null}
})
};
fetch('https://api.dittowords.com/v2/textItems/linkFigmaNodes', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.dittowords.com/v2/textItems/linkFigmaNodes",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'projectId' => 'project-id-1',
'textItemId' => 'greeting',
'figma' => [
'nodeIds' => [
'1:23',
'1:24'
],
'branchId' => null
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.dittowords.com/v2/textItems/linkFigmaNodes"
payload := strings.NewReader("{\n \"projectId\": \"project-id-1\",\n \"textItemId\": \"greeting\",\n \"figma\": {\n \"nodeIds\": [\n \"1:23\",\n \"1:24\"\n ],\n \"branchId\": null\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.dittowords.com/v2/textItems/linkFigmaNodes")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"projectId\": \"project-id-1\",\n \"textItemId\": \"greeting\",\n \"figma\": {\n \"nodeIds\": [\n \"1:23\",\n \"1:24\"\n ],\n \"branchId\": null\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.dittowords.com/v2/textItems/linkFigmaNodes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"projectId\": \"project-id-1\",\n \"textItemId\": \"greeting\",\n \"figma\": {\n \"nodeIds\": [\n \"1:23\",\n \"1:24\"\n ],\n \"branchId\": null\n }\n}"
response = http.request(request)
puts response.read_body{
"projectId": "project-id-1",
"textItemId": "greeting",
"branchId": null,
"results": [
{
"figmaNodeId": "1:23",
"outcome": "linked",
"linkedTextItemId": "greeting"
},
{
"figmaNodeId": "1:24",
"outcome": "not_found",
"message": "This Figma text node is not in the cache for the target project context. Sync first, then retry."
}
]
}{
"message": "Project \"project-id-1\" is not linked to Figma."
}{
"message": "Text item \"greeting\" was not found in project \"project-id-1\"."
}