Text Library API
The Text Library API lets another system read and manage the texts and folders of the Text Library in Studio, the reusable texts that Smartforms and PDF templates refer to. It does not cover the separate Text Library application. To see the library in Studio, read Text Library.
Every call is made on your own company. Get a token from a Standard API client with the scope api.external, as described in Authentication. There is no customer parameter.
The host is the Studio API host, with the path /Integrations/textlibrary:
https://api.smartforms.metaforce.net/Integrations/textlibrary
Only shared folders are visible. A folder that is private to a user is never returned and is answered with 404.
Folders
| Call | What it does |
|---|---|
GET /folders | Lists the folders. Each has id, name, parentFolderId, isDefault and code. Start here to find the folder id you need for a text. |
POST /folders | Creates a folder. name is required. parentFolderId nests it one level under an existing folder. code is optional. |
PUT /folders/{id} | Renames a folder or sets its code. A field you leave out keeps its value. |
DELETE /folders/{id} | Deletes a folder. The folder must be empty. |
- A code is a short name that references can use in place of the folder name, so references keep working if you rename the folder.
- Folders nest one level only. Creating a folder under a subfolder is answered with
400. - A name or code that is already taken is answered with
409. So is deleting a folder that still holds texts or subfolders.
{
"name": "Nordic HR",
"code": "nordic-hr"
}Texts
| Call | What it does |
|---|---|
GET /search | Searches texts and folders. |
GET /texts/{id} | Reads one text. |
POST /texts | Creates a text. |
PUT /texts/{id} | Updates a text. |
DELETE /texts/{id} | Deletes a text. |
A text has these fields:
| Field | What it is |
|---|---|
folderId | The folder the text belongs to. Required. |
code | Identifies the text within its folder. Required. |
name, description | Free text. |
contentType | A number: 0 for plain text, 1 for rich text or 2 for HTML. The names are not accepted. |
isPublic | Whether the text is public. |
defaultLanguage | The language code used when a language is not asked for. |
translations | The content per language code, as { "en": { "content": "..." } }. |
{
"folderId": "64e4a31fdf775xxxxxxxxxx1",
"code": "sick-leave",
"name": "Sick leave",
"contentType": 0,
"defaultLanguage": "en",
"translations": {
"en": { "content": "You can report sick leave from day one." },
"nb": { "content": "Du kan melde sykefravær fra første dag." }
}
}Property names are written in camel case, in requests and in responses.
- A missing
folderIdorcodeis answered with400. - A
folderIdthat does not exist is answered with404. - A
codethat is already used in the folder, or anywhere else under the same top-level folder and its subfolders, is answered with409. - On update, the fields are replaced by what you send, but translations are merged. A language you leave out keeps the content it already had.
A text in a response has id, folderId, code, name, description, contentType, isPublic, defaultLanguage, translations, createdDate and updatedDate. contentType is a number. Each language in translations has its content, a source and updatedAt, the time that language was last changed. source is 0 for text that a person wrote and 1 for an automatic translation.
{
"id": "64e4a31fdf775xxxxxxxxxx2",
"folderId": "64e4a31fdf775xxxxxxxxxx1",
"code": "sick-leave",
"name": "Sick leave",
"contentType": 0,
"isPublic": false,
"defaultLanguage": "en",
"translations": {
"en": {
"content": "You can report sick leave from day one.",
"source": 0,
"updatedAt": "2026-09-30T08:15:00Z"
}
},
"createdDate": "2026-09-30T08:15:00Z",
"updatedDate": "2026-09-30T08:15:00Z"
}The code is what a reference in a Smartform points at, for example [[ LIB : nordic-hr : sick-leave ]]. See Using Texts.
Search
GET /search takes these query parameters:
| Parameter | What it does |
|---|---|
q | Free text. Matches the code, name or description of a text and the name of a folder. Leave it out to list everything. |
page | Page number, counted from 0. |
pageSize | Texts per page. The default is 10 and the maximum is 100. |
sortBy | code (default), name or description. |
descending | true reverses the order. |
The response has texts, with items, page, pageSize, totalCount and totalPages, and folders. Texts are paged and folders are not.
Example
const axios = require('axios').default;
async function searchTexts(accessToken) {
const response = await axios({
method: 'GET',
url: 'https://api.smartforms.metaforce.net/Integrations/textlibrary/search?q=sick&pageSize=20',
headers: { 'Authorization': `Bearer ${accessToken}` }
});
for (const text of response.data.texts.items) {
console.log(text.code, text.name);
}
}