Glossaries¶
Manage glossaries and terminology to ensure consistent translations.
GlossaryEntry Structure¶
Each glossary entry supports multi-language translations via a single translations dict.
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
auto | Auto-generated: term_<hex8> |
term |
string |
yes | Source term (case-insensitive matching) |
translations |
dict[string, string] |
yes (min 1) | Target language -> translated term mapping, e.g. {"de": "Bluthochdruck", "fr": "hypertension"} |
context |
string |
no | Disambiguates polysemous terms, e.g. "medical context" |
domain |
string |
no | Subject domain, e.g. "medical", "finance" |
forbidden_alternatives |
list[string] |
no | Terms the translator must NOT use |
status |
"approved" | "pending" | "deprecated" |
no | Default: "approved" |
suggested_by |
string |
auto | UUID of submitting user (only on entries added via POST /entries) |
suggested_at |
string |
auto | ISO 8601 timestamp (only on entries added via POST /entries) |
GET /v1/glossaries¶
List all glossaries for the authenticated account.
Authentication
Header: X-API-Key: your_api_key
Status: 200 OK
Response¶
{
"data": [
{
"glossary_id": "gloss_abc12345",
"name": "Marketing Terms",
"description": "Brand-specific terminology for marketing content.",
"scope": "private",
"entry_count": 85,
"created_at": "2026-01-15T09:00:00+00:00",
"updated_at": "2026-03-10T14:30:00+00:00"
},
{
"glossary_id": "gloss_def67890",
"name": "Medical Terminology",
"description": "Shared medical glossary for the whole account.",
"scope": "account",
"entry_count": 320,
"created_at": "2026-02-01T11:00:00+00:00",
"updated_at": "2026-03-18T08:15:00+00:00"
}
]
}
Examples¶
POST /v1/glossaries¶
Create a new glossary.
Authentication
Header: X-API-Key: your_api_key
Content-Type: application/json
Status: 201 Created
Request Body¶
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string |
yes | -- | Glossary name (max 100 chars). |
description |
string |
no | null |
Description of the glossary's purpose. |
scope |
"private" | "account" |
no | "private" |
"private" = bound to API key; "account" = shared across all account members (requires Business/Enterprise plan). |
Account Glossaries
Account glossaries require a Business or Enterprise plan. Creating a glossary with scope: "account" on lower plans returns 403 Forbidden.
Response (201)¶
{
"glossary_id": "gloss_abc12345",
"name": "Marketing Terms",
"description": "Brand-specific terminology for marketing content.",
"scope": "private",
"entry_count": 0,
"created_at": "2026-03-20T10:00:00+00:00",
"updated_at": "2026-03-20T10:00:00+00:00"
}
Examples¶
const response = await fetch("https://app.falara.io/v1/glossaries", {
method: "POST",
headers: {
"X-API-Key": FALARA_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Marketing Terms",
description: "Brand-specific terminology for marketing content.",
scope: "private",
}),
});
const data = await response.json();
console.log(data);
GET /v1/glossaries/{glossary_id}¶
Get a single glossary with its entries.
Authentication
Header: X-API-Key: your_api_key
Status: 200 OK
Response¶
{
"glossary_id": "gloss_abc12345",
"name": "Marketing Terms",
"description": "Brand-specific terminology for marketing content.",
"scope": "private",
"entry_count": 85,
"entries": [
{
"id": "term_a1b2c3d4",
"term": "Markenidentität",
"translations": {
"en": "brand identity",
"fr": "identité de marque"
},
"context": "Used in branding guidelines.",
"domain": "marketing",
"forbidden_alternatives": [],
"status": "approved"
}
],
"created_at": "2026-01-15T09:00:00+00:00",
"updated_at": "2026-03-10T14:30:00+00:00"
}
PUT /v1/glossaries/{glossary_id}¶
Update glossary metadata (name, description).
Authentication
Header: X-API-Key: your_api_key
Content-Type: application/json
Status: 200 OK
Request Body¶
| Field | Type | Required | Description |
|---|---|---|---|
name |
string |
no | Updated glossary name. |
description |
string |
no | Updated description. |
Response (200)¶
Returns the updated glossary object.
DELETE /v1/glossaries/{glossary_id}¶
Delete a glossary and all its entries. This action is irreversible.
Authentication
Header: X-API-Key: your_api_key
Status: 204 No Content
Warning
Deleting a glossary does not affect jobs that already used it. Future jobs referencing this glossary ID will return a 404 error.
Examples¶
POST /v1/glossaries/{glossary_id}/entries¶
Add entries to an existing glossary.
Authentication
Header: X-API-Key: your_api_key
Content-Type: application/json
Status: 201 Created
Request Body¶
{
"entries": [
{
"term": "Markenidentität",
"translations": {
"en": "brand identity",
"fr": "identité de marque"
},
"context": "Used in branding guidelines.",
"domain": "marketing"
},
{
"term": "Zielgruppe",
"translations": {
"en": "target audience",
"fr": "public cible"
}
}
]
}
See GlossaryEntry Structure for all available fields.
Response (201)¶
Examples¶
curl -X POST "https://app.falara.io/v1/glossaries/gloss_abc12345/entries" \
-H "X-API-Key: $FALARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entries": [
{
"term": "Markenidentität",
"translations": {"en": "brand identity", "fr": "identité de marque"}
},
{
"term": "Zielgruppe",
"translations": {"en": "target audience"}
}
]
}'
import requests
response = requests.post(
f"https://app.falara.io/v1/glossaries/{glossary_id}/entries",
headers={"X-API-Key": FALARA_API_KEY},
json={
"entries": [
{
"term": "Markenidentität",
"translations": {"en": "brand identity", "fr": "identité de marque"},
},
{
"term": "Zielgruppe",
"translations": {"en": "target audience"},
},
]
},
)
print(response.json())
const response = await fetch(
`https://app.falara.io/v1/glossaries/${glossaryId}/entries`,
{
method: "POST",
headers: {
"X-API-Key": FALARA_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
entries: [
{
term: "Markenidentität",
translations: { en: "brand identity", fr: "identité de marque" },
},
{
term: "Zielgruppe",
translations: { en: "target audience" },
},
],
}),
}
);
const data = await response.json();
console.log(data);
Bulk Import¶
Import glossary entries from TBX, CSV, or Excel files using a two-step preview then commit flow.
POST /v1/glossaries/upload/preview¶
Parse and validate a glossary file without committing changes. Use this to review what will be imported before writing to the glossary.
Authentication
Header: X-API-Key: your_api_key
Content-Type: multipart/form-data
Status: 200 OK
Form Fields¶
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
file |
file |
yes | -- | TBX, CSV, or XLSX file (max 10 MB). |
type |
string |
no | "glossary" |
Upload type. |
glossary_id |
string |
no | null |
Existing glossary ID. If provided, the preview shows which entries are new, updated, or unchanged. |
column_mapping |
string (JSON) |
no | null |
Column mapping for CSV files (e.g., {"term": "A", "translations.en": "B", "context": "C"}). |
Response (200)¶
{
"upload_id": "upl_abc123",
"entries_parsed": 150,
"entries_new": 120,
"entries_updated": 25,
"entries_unchanged": 5,
"errors": [],
"sample_entries": [
{
"term": "Markenidentität",
"translations": {"en": "brand identity", "fr": "identité de marque"},
"context": "branding",
"status": "new"
},
{
"term": "Zielgruppe",
"translations": {"en": "target audience"},
"context": null,
"status": "updated"
}
]
}
Upload Expiration
Previewed uploads expire after 1 hour. Commit before then, or re-upload.
Examples¶
import requests
with open("terminology.tbx", "rb") as f:
response = requests.post(
"https://app.falara.io/v1/glossaries/upload/preview",
headers={"X-API-Key": FALARA_API_KEY},
files={"file": ("terminology.tbx", f)},
data={"glossary_id": "gloss_abc12345"},
)
preview = response.json()
print(f"New: {preview['entries_new']}, Updated: {preview['entries_updated']}")
const formData = new FormData();
formData.append("file", tbxBlob, "terminology.tbx");
formData.append("glossary_id", "gloss_abc12345");
const response = await fetch(
"https://app.falara.io/v1/glossaries/upload/preview",
{
method: "POST",
headers: { "X-API-Key": FALARA_API_KEY },
body: formData,
}
);
const preview = await response.json();
console.log(`New: ${preview.entries_new}, Updated: ${preview.entries_updated}`);
POST /v1/glossaries/upload/commit¶
Commit a previously previewed upload to a glossary.
Authentication
Header: X-API-Key: your_api_key
Content-Type: application/json
Status: 201 Created
Request Body¶
| Field | Type | Required | Description |
|---|---|---|---|
upload_id |
string |
yes | The upload_id from the preview response. |
glossary_id |
string |
no | Target glossary ID. If omitted, a new glossary is created. |
Response (201)¶
{
"glossary_id": "gloss_abc12345",
"entries_added": 120,
"entries_updated": 25,
"entries_unchanged": 5,
"total_entries": 210
}
Examples¶
import requests
response = requests.post(
"https://app.falara.io/v1/glossaries/upload/commit",
headers={"X-API-Key": FALARA_API_KEY},
json={
"upload_id": "upl_abc123",
"glossary_id": "gloss_abc12345",
},
)
result = response.json()
print(f"Added: {result['entries_added']}, Total: {result['total_entries']}")
const response = await fetch(
"https://app.falara.io/v1/glossaries/upload/commit",
{
method: "POST",
headers: {
"X-API-Key": FALARA_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
upload_id: "upl_abc123",
glossary_id: "gloss_abc12345",
}),
}
);
const result = await response.json();
console.log(`Added: ${result.entries_added}, Total: ${result.total_entries}`);
Errors¶
| Status | Description |
|---|---|
401 |
Invalid or missing API key. |
404 |
Upload ID expired or not found. |
422 |
Validation error. |
Using Glossaries in Jobs¶
Reference glossaries when creating a translation job to enforce consistent terminology.
Reference by ID¶
Pass one or more glossary IDs in the glossary_ids array (up to 5):
{
"mode": "translation",
"source_lang": "de",
"target_lang": "en",
"text": "Unsere Markenidentität spricht die Zielgruppe direkt an.",
"glossary_ids": ["gloss_abc12345"]
}
Multiple Glossaries¶
Combine up to 5 glossaries per job:
Glossary Priority¶
Control which glossary takes precedence when entries conflict:
| Value | Description |
|---|---|
"account_first" |
Account-scoped glossaries take precedence over private ones. (default) |
"private_first" |
Private glossaries take precedence over account-scoped ones. |
Inline Entries¶
You can also pass ad-hoc glossary entries directly in the request body. Inline entries take precedence over stored glossary entries when there is a conflict.
{
"mode": "translation",
"source_lang": "de",
"target_lang": "en",
"text": "Die Qualität unserer Produkte spricht für sich.",
"glossary_ids": ["gloss_abc12345"],
"glossary": [
{
"term": "Qualität",
"translations": {"en": "quality"}
}
]
}
Backward Compatibility
The legacy glossary_id parameter (single string) is still accepted for backward compatibility. Prefer glossary_ids (array) for new integrations.