Settings API
Base path /api/settings — JWT required. Per-user preferences and API-key storage for the free/optional third-party data connectors (USDA, OpenAlex, openFDA, Data.gov, FRED). Every user gets a UserSettings row lazily — if none exists yet, GET returns sensible defaults without creating one.
GET /api/settings
Returns the caller's settings. Stored provider keys are never returned in plaintext — only a has*Key boolean indicating whether one is set.
{
"preferredModel": "claude-sonnet-4-6",
"enableDsld": true,
"enableApis": true,
"geoNamesUser": "my-geonames-username",
"templates": { "...": "user-defined schema-mapper templates" },
"hasUsdaKey": true,
"hasOpenAlexKey": false,
"hasOpenFdaKey": false,
"hasDataGovKey": true,
"hasFredKey": false
}If no UserSettings row exists yet: { "preferredModel": "claude-sonnet-4-6", "enableDsld": true, "enableApis": true }.
PUT /api/settings
Send only the fields you want to change (partial update; upserts the row). All fields are optional.
| Field | Type | Storage | Notes |
|---|---|---|---|
preferredModel | string | plain | Which AI model the research agent defaults to |
enableDsld | boolean | plain | Toggle the NIH DSLD connector |
enableApis | boolean | plain | Master toggle for live API connectors |
geoNamesUser | string | plain | GeoNames username (not a secret, so stored unencrypted) |
templates | any | plain (JSON) | Schema-mapper export templates |
usdaKey | string | null | encrypted | USDA FoodData Central key |
openAlexKey | string | null | encrypted | OpenAlex key |
openFdaKey | string | null | encrypted | openFDA key |
dataGovKey | string | null | encrypted | Data.gov key |
fredKey | string | null | encrypted | FRED (Federal Reserve) key |
Key fields are encrypted at rest (lib/crypto.js, ENCRYPTION_KEY-backed) before storage — sending null for any key field clears it; omitting a field is a no-op (leaves the stored value untouched).
Responses
200→{ "updated": true }400→ Zod validation error —{ "error": [...] }503→{ "error": "Secret storage is not configured on the server." }ifENCRYPTION_KEYisn't set server-side and the request tried to write a key field.
→ Related: Connectors · Research