curl --request GET \
--url https://api.dittowords.com/v2/textItems \
--header 'Authorization: <api-key>'import requests
url = "https://api.dittowords.com/v2/textItems"
headers = {"Authorization": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: '<api-key>'}};
fetch('https://api.dittowords.com/v2/textItems', 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",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.dittowords.com/v2/textItems"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.dittowords.com/v2/textItems")
.header("Authorization", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.dittowords.com/v2/textItems")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = '<api-key>'
response = http.request(request)
puts response.read_body[
{
"id": "base-text-item-dev-id",
"text": "Save changes",
"richText": "Save changes",
"variantId": null,
"pluralForm": null,
"projectId": null,
"baseId": "base-dev-id",
"folderId": "buttons-folder-dev-id",
"notes": "base notes",
"characterLimit": null,
"tags": [
"baseTag1",
"baseTag2"
],
"integrated": true,
"variableIds": []
},
{
"id": "text-item-dev-id",
"text": "Save changes",
"richText": "<strong>Save</strong> changes",
"variantId": null,
"pluralForm": null,
"projectId": "project-dev-id",
"baseId": "base-dev-id",
"baseTextItemId": "base-text-item-dev-id",
"blockName": "block name",
"status": "NONE",
"assignee": "john@example.com",
"notes": "base notes",
"characterLimit": null,
"tags": [
"baseTag1",
"baseTag2"
],
"integrated": true,
"variableIds": []
},
{
"id": "text-item-dev-id",
"text": "Enregistrer les modifications",
"richText": "<em>Enregistrer</em> les modifications",
"variantId": "french",
"pluralForm": null,
"projectId": "project-dev-id",
"baseId": "base-dev-id",
"baseTextItemId": "base-text-item-dev-id",
"blockName": "block name",
"status": "WIP",
"assignee": "john@example.com",
"notes": "french notes",
"characterLimit": 40,
"tags": [
"baseTag1",
"baseTag2"
],
"integrated": true,
"variableIds": []
},
{
"id": "another-text-item",
"text": "Hello {{name}}, you have 3 messages",
"richText": "Hello {{name}}, you have 3 messages",
"variantId": null,
"pluralForm": "other",
"projectId": "another-project",
"baseId": null,
"baseTextItemId": null,
"blockName": null,
"status": "FINAL",
"assignee": null,
"notes": "base notes",
"characterLimit": 60,
"tags": [
"baseTag1",
"baseTag2"
],
"integrated": false,
"variableIds": [
"name"
]
}
]Fetch text items
Returns a list of text items in your workspace.
curl --request GET \
--url https://api.dittowords.com/v2/textItems \
--header 'Authorization: <api-key>'import requests
url = "https://api.dittowords.com/v2/textItems"
headers = {"Authorization": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: '<api-key>'}};
fetch('https://api.dittowords.com/v2/textItems', 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",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.dittowords.com/v2/textItems"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.dittowords.com/v2/textItems")
.header("Authorization", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.dittowords.com/v2/textItems")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = '<api-key>'
response = http.request(request)
puts response.read_body[
{
"id": "base-text-item-dev-id",
"text": "Save changes",
"richText": "Save changes",
"variantId": null,
"pluralForm": null,
"projectId": null,
"baseId": "base-dev-id",
"folderId": "buttons-folder-dev-id",
"notes": "base notes",
"characterLimit": null,
"tags": [
"baseTag1",
"baseTag2"
],
"integrated": true,
"variableIds": []
},
{
"id": "text-item-dev-id",
"text": "Save changes",
"richText": "<strong>Save</strong> changes",
"variantId": null,
"pluralForm": null,
"projectId": "project-dev-id",
"baseId": "base-dev-id",
"baseTextItemId": "base-text-item-dev-id",
"blockName": "block name",
"status": "NONE",
"assignee": "john@example.com",
"notes": "base notes",
"characterLimit": null,
"tags": [
"baseTag1",
"baseTag2"
],
"integrated": true,
"variableIds": []
},
{
"id": "text-item-dev-id",
"text": "Enregistrer les modifications",
"richText": "<em>Enregistrer</em> les modifications",
"variantId": "french",
"pluralForm": null,
"projectId": "project-dev-id",
"baseId": "base-dev-id",
"baseTextItemId": "base-text-item-dev-id",
"blockName": "block name",
"status": "WIP",
"assignee": "john@example.com",
"notes": "french notes",
"characterLimit": 40,
"tags": [
"baseTag1",
"baseTag2"
],
"integrated": true,
"variableIds": []
},
{
"id": "another-text-item",
"text": "Hello {{name}}, you have 3 messages",
"richText": "Hello {{name}}, you have 3 messages",
"variantId": null,
"pluralForm": "other",
"projectId": "another-project",
"baseId": null,
"baseTextItemId": null,
"blockName": null,
"status": "FINAL",
"assignee": null,
"notes": "base notes",
"characterLimit": 60,
"tags": [
"baseTag1",
"baseTag2"
],
"integrated": false,
"variableIds": [
"name"
]
}
]Authorizations
Query Parameters
Stringified JSON filter object. Supports the following filter fields:
projects: array of objects withid(project developer ID)bases: array of objects withid(base developer ID)variants: array of objects withid(variant developer ID,base, orall)statuses: array of status strings (NONE,WIP,REVIEW,FINAL). These are stored status keys; by default the web app and Figma plugin display them as NONE = "Draft", WIP = "In Progress", REVIEW = "In Review", FINAL = "Final" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set).tags: object withvalues(array of tag strings) and optionaloperator(ANDorOR, defaults toOR)assignee: email string to match assigned text items, ornullfor unassignedintegrated: boolean value to filter by items that are or are not integrated into development
Without any filters, the response will include text items from all projects and no base text items. If a projects filter is provided, only text items from the specified projects will be returned. If a bases filter is provided, only text items from the specified bases will be returned. The projects and bases filters may be used together to return items from both sources. (More details about bases coming soon!)
By default, only the base text will be returned for each text item. Provide a variants filter to specify which variants of the filtered text items to include. Use all to return all variants, including base text. If individual variants are specified, base text will only be returned if base is included in the filter.
For each text item that has plurals defined, separate entries will be returned for each plural form, plus the primary text with pluralForm: null. This applies to base text and variants.
The status and assignee filters apply only to project text items. Base text items do not contain these fields and will be returned unfiltered. When pairing variants with a status or assignee filter, variant data will only be returned if both the base and variant status/assignee match the filter.
Example: {"projects":[{"id":"project-id"}], "variants":[{"id":"french"}], "statuses":["NONE","WIP","FINAL","REVIEW"], "tags":{"values":["tag-1","tag-2"],"operator":"AND"}, "assignee":"user@example.com", "integrated":true}
Sort order for the returned text items (default: id):
idsorts all items alphabetically by developer ID.project_ordergroups items by project, returned alphabetically by project developer ID, then sorts within projects based on the custom sort order set up in the web app.
id, project_order When set to 'html', includes HTML-formatted rich text in the response.
html Response
Returns an array of text items matching the filter criteria
- Project
- Base
The Developer ID of the project text item
The plaintext content of the project text item. Returns the variant's text when variantId is not null.
The notes on the project text item. Returns the variant's notes when variantId is not null.
The character limit set on this project text item, or null if no limit is set. Returns the variant's character limit when variantId is not null.
Array of tags associated with the project text item. Returns the base tags value in all responses; variants do not have their own tags.
Whether this project text item has been marked as integrated into development
Array of Developer IDs of variables used in this base or variant text
The Developer ID of this variant, or null for base text
one, two, few, many, zero, other, null The Developer ID of the project this text item belongs to
The Developer ID of the base this text item's project is connected to, or null if not connected.
The Developer ID of the base text item this text item was derived from, or null if not represented in a base.
The status of the text item. Returns the variant's status when variantId is not null. These are stored status keys; by default the web app and Figma plugin display them as NONE = "Draft", WIP = "In Progress", REVIEW = "In Review", FINAL = "Final" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set).
The email of the user assigned to this text item, or null if unassigned. Returns the variant's assignee when variantId is not null.
The name of the block this text item belongs to, or null if it is not in a block.
HTML-formatted version of the text content. Only included when richText=html query parameter is provided
[
{
"id": "base-text-item-dev-id",
"text": "Save changes",
"richText": "Save changes",
"variantId": null,
"pluralForm": null,
"projectId": null,
"baseId": "base-dev-id",
"folderId": "buttons-folder-dev-id",
"notes": "base notes",
"characterLimit": null,
"tags": ["baseTag1", "baseTag2"],
"integrated": true,
"variableIds": []
},
{
"id": "text-item-dev-id",
"text": "Save changes",
"richText": "<strong>Save</strong> changes",
"variantId": null,
"pluralForm": null,
"projectId": "project-dev-id",
"baseId": "base-dev-id",
"baseTextItemId": "base-text-item-dev-id",
"blockName": "block name",
"status": "NONE",
"assignee": "john@example.com",
"notes": "base notes",
"characterLimit": null,
"tags": ["baseTag1", "baseTag2"],
"integrated": true,
"variableIds": []
},
{
"id": "text-item-dev-id",
"text": "Enregistrer les modifications",
"richText": "<em>Enregistrer</em> les modifications",
"variantId": "french",
"pluralForm": null,
"projectId": "project-dev-id",
"baseId": "base-dev-id",
"baseTextItemId": "base-text-item-dev-id",
"blockName": "block name",
"status": "WIP",
"assignee": "john@example.com",
"notes": "french notes",
"characterLimit": 40,
"tags": ["baseTag1", "baseTag2"],
"integrated": true,
"variableIds": []
},
{
"id": "another-text-item",
"text": "Hello {{name}}, you have 3 messages",
"richText": "Hello {{name}}, you have 3 messages",
"variantId": null,
"pluralForm": "other",
"projectId": "another-project",
"baseId": null,
"baseTextItemId": null,
"blockName": null,
"status": "FINAL",
"assignee": null,
"notes": "base notes",
"characterLimit": 60,
"tags": ["baseTag1", "baseTag2"],
"integrated": false,
"variableIds": ["name"]
}
]