Platform settings and logs
Platform settings are the Chat service's configuration values. Each setting takes its value from one of three places: an override saved through Update a platform setting, the deployment configuration, or a built-in default. Settings that are only read when the service starts can't be changed through the API; change them in the deployment configuration.
Settings are grouped into sections:
- Core Application: the installation's public addresses, and values read only at start-up.
- CORS: the browser origins allowed to call the API, and session cookie attributes.
- Entra ID SSO: Microsoft Entra ID sign-in, including whether it is enabled, the tenant and application registration, and how users are provisioned and assigned roles. See also Single sign-on configuration.
- Microsoft 365 Files and Microsoft 365 Mail & Teams: the application registrations those integrations use (by default the sign-in registration), request timeouts, and automatic re-sync.
- Network Triggers: polling of mailboxes and Teams channels that start networks.
- Email: the outbound mail server, its credentials, and the sender address.
- Atlassian OAuth: the Jira and Confluence OAuth application and webhook limits.
- LLM Providers, Catalog & Routing, LLM & Analysis, and Vector Analysis: embedding and model-selection settings, and how the service reaches the Model Catalog and Networks.
- Audio: the speech-to-text service, its credential, and the transcription models.
- Database Runtime: connection pool tuning.
Secrets are never returned. A secret that is set reads as [REDACTED], and one that is not set reads as an empty string. Settings and error logs are unavailable while the licence is restricted: every call on this page returns 402 until a valid licence is installed.
Administrator access. Every endpoint on this page requires an administrator account.
- GET /admin/settings Retrieve platform settings
- PUT /admin/settings Update a platform setting
- GET /admin/logs/errors List error log entries
Paths are relative to /api
The setting object
One entry in a section's settings array.
Attributes
-
keystringIdentifier of the setting. Pass it unchanged to Update a platform setting.
-
groupstringName of the section the setting belongs to.
-
typestringHow the value is interpreted:
string,secret,integer,float,boolean, orcsv(a comma-separated list). -
descriptionstringWhat the setting controls.
-
editablebooleanWhether the setting can be changed through the API.
-
requires_restartbooleantruefor settings read only when the service starts. These are not editable through the API. -
sourcestringWhere the effective value comes from:
db_override(an override saved through the API),environment(the deployment configuration), ordefault(the built-in default).Possible values-
db_override -
environment -
default
-
-
redactedbooleanWhether the setting is a secret whose value is withheld.
-
valuestringThe effective value. Booleans and numbers are returned as JSON booleans and numbers, and
csvvalues as one string of comma-separated items. Secrets read as[REDACTED]when set and as an empty string when not. -
override_valuenullable stringThe override saved through the API, redacted in the same way for secrets, or
nullwhen there is none. -
override_pendingbooleantruewhen an override is saved for a setting that can't be changed through the API. That override is not applied.
{
"key": "<SETTING_KEY>",
"group": "Email",
"type": "string",
"description": "SMTP host used for outbound mail.",
"editable": true,
"requires_restart": false,
"source": "db_override",
"redacted": false,
"value": "smtp.example.com",
"override_value": "smtp.example.com",
"override_pending": false
} Retrieve platform settings
GET /api/admin/settings
Returns every Chat service setting with its effective value.
Returns the settings grouped by section. Each entry reports its effective value, where that value comes from, whether it can be changed through Update a platform setting, and any override that has been saved. Secret values are redacted.
- Authentication
- Bearer token How it works
- Permission
- Requires an administrator account.
Parameters
No parameters.
Returns
Returns service (always chat), environment (the environment label from the service's configuration, development when none is set), fetched_at (when the settings were read, in ISO 8601), and groups, an array of sections, each with a name and a settings array of setting objects.
Errors
- 403 The caller is not an administrator.
curl "$VDF_BASE_URL/api/admin/settings" \
-H "Authorization: Bearer $VDF_ACCESS_TOKEN" const response = await fetch(`${process.env.VDF_BASE_URL}/api/admin/settings`, {
headers: {
Authorization: `Bearer ${process.env.VDF_ACCESS_TOKEN}`,
},
});
if (!response.ok) throw new Error(`Request failed with status ${response.status}`);
const data = await response.json(); import os
import requests
response = requests.get(
f"{os.environ['VDF_BASE_URL']}/api/admin/settings",
headers={"Authorization": f"Bearer {os.environ['VDF_ACCESS_TOKEN']}"},
timeout=30,
)
response.raise_for_status()
data = response.json() {
"service": "chat",
"environment": "development",
"fetched_at": "2026-09-11T08:30:00.512311+00:00",
"groups": [
{
"name": "Email",
"settings": [
{
"key": "<SETTING_KEY>",
"group": "Email",
"type": "string",
"description": "SMTP host used for outbound mail.",
"editable": true,
"requires_restart": false,
"source": "db_override",
"redacted": false,
"value": "smtp.example.com",
"override_value": "smtp.example.com",
"override_pending": false
},
{
"key": "<SECRET_SETTING_KEY>",
"group": "Email",
"type": "secret",
"description": "SMTP password.",
"editable": true,
"requires_restart": false,
"source": "environment",
"redacted": true,
"value": "[REDACTED]",
"override_value": null,
"override_pending": false
}
]
}
]
} Update a platform setting
PUT /api/admin/settings
Saves or removes the override for one setting.
Saves an override for the setting identified by key. Only settings whose editable is true can be changed. The value is converted to the setting's type before it is stored:
boolean:true,1,yes,y, andon, in any letter case, mean true; any other value means false.integer: the value must be a whole number.float: the value must be a number.csv: items are trimmed and empty items are dropped.
Some settings are validated further; for example, the speech-to-text service address must be an http or https origin without a path.
Send null or an empty string to remove the override, so that the setting falls back to the deployment configuration or its default. [REDACTED] is not a special value: sending it stores that text as the new secret. To keep a secret unchanged, don't send it.
The saved value applies immediately on the server that handles the request, and on the rest of the Chat service within about ten seconds.
- Authentication
- Bearer token How it works
- Permission
- Requires an administrator account.
Body parameters application/json
-
keystring RequiredThe setting's
key, as returned by Retrieve platform settings. -
valuestringThe new value. Strings, numbers, and booleans are accepted and converted to the setting's type.
nullor an empty string removes the override.
Returns
Returns a success marker with the service and the key that was changed.
Errors
- 400
keyis missing, the setting does not exist or can't be changed through the API, or the value can't be converted to the setting's type or fails its validation. - 403 The caller is not an administrator.
- 500 The override could not be stored.
curl -X PUT "$VDF_BASE_URL/api/admin/settings" \
-H "Authorization: Bearer $VDF_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"key": "<SETTING_KEY>",
"value": "smtp.example.com"
}' const response = await fetch(`${process.env.VDF_BASE_URL}/api/admin/settings`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.VDF_ACCESS_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
key: '<SETTING_KEY>',
value: 'smtp.example.com',
}),
});
if (!response.ok) throw new Error(`Request failed with status ${response.status}`);
const data = await response.json(); import os
import requests
response = requests.put(
f"{os.environ['VDF_BASE_URL']}/api/admin/settings",
headers={"Authorization": f"Bearer {os.environ['VDF_ACCESS_TOKEN']}"},
json={
"key": "<SETTING_KEY>",
"value": "smtp.example.com",
},
timeout=30,
)
response.raise_for_status()
data = response.json() {
"success": true,
"service": "chat",
"key": "<SETTING_KEY>"
} List error log entries
GET /api/admin/logs/errors
Searches the Chat service log for ERROR and WARNING entries; entries at other levels are never returned. Without date_from, only the last seven days are searched. Only the first line of each entry is returned, and messages are cut to 500 characters. On a very large log, only the most recent part of the file is searched.
Matches are numbered from the start of the time window, so page 1 holds the earliest matching entries; within a page, entries are listed newest first. Use pages to reach the most recent entries. If the service has not written a log yet, the response has an empty logs array and no pages field.
- Authentication
- Bearer token How it works
- Permission
- Requires an administrator account.
Query parameters
-
pageintegerPage number, starting at 1.
-
limitintegerEntries per page, at least 1. Values above 100 are treated as 100.
-
levelstringERRORorWARNING, in any letter case. Omit it to return both. -
date_fromstringFirst day to search, as
YYYY-MM-DDin the server's local time. An invalid date is ignored. -
date_tostringLast day to search, inclusive, as
YYYY-MM-DDin the server's local time. An invalid date is ignored. -
searchstringText the message must contain, matched case-insensitively.
-
logger_namestringText the name of the component that wrote the entry must contain, matched case-insensitively.
Returns
Returns logs, an array of entries with timestamp (server local time, as YYYY-MM-DD HH:MM:SS,mmm), level, logger_name, and message, together with total matches, page, limit, and pages.
Errors
- 403 The caller is not an administrator.
- 500 The log could not be read.
curl "$VDF_BASE_URL/api/admin/logs/errors?date_from=2026-09-04&limit=50" \
-H "Authorization: Bearer $VDF_ACCESS_TOKEN" const response = await fetch(`${process.env.VDF_BASE_URL}/api/admin/logs/errors?date_from=2026-09-04&limit=50`, {
headers: {
Authorization: `Bearer ${process.env.VDF_ACCESS_TOKEN}`,
},
});
if (!response.ok) throw new Error(`Request failed with status ${response.status}`);
const data = await response.json(); import os
import requests
response = requests.get(
f"{os.environ['VDF_BASE_URL']}/api/admin/logs/errors",
headers={"Authorization": f"Bearer {os.environ['VDF_ACCESS_TOKEN']}"},
params={
"date_from": "2026-09-04",
"limit": 50,
},
timeout=30,
)
response.raise_for_status()
data = response.json() {
"success": true,
"logs": [
{
"timestamp": "2026-09-10 14:02:11,512",
"level": "ERROR",
"logger_name": "app",
"message": "License usage report failed"
},
{
"timestamp": "2026-09-10 09:15:42,087",
"level": "WARNING",
"logger_name": "app",
"message": "No user found for id: 57"
}
],
"total": 2,
"page": 1,
"limit": 50,
"pages": 1
}