temetro

AI configuration

Per-user AI provider settings and the migration import endpoint.

AI settings are user-scoped (like /api/settings) — they follow the signed-in user across clinics. Provider API keys are encrypted at rest and never returned by the API.

MethodPathAuthReturns
GET/api/ai/configSigned inNon-secret config + apiKeySet
PUT/api/ai/configSigned inThe saved config
POST/api/ai/testSigned in{ ok, message }
POST/api/ai/importpatient:write{ created, failed }

The config object

{
  "config": {
    "mode": "local",
    "provider": "anthropic",
    "ollamaBaseUrl": "http://localhost:11434",
    "ollamaModel": "llama3.1",
    "defaultModel": "claude-sonnet-4-6",
    "defaultEffort": "medium",
    "veilLevel": "full",
    "apiKeySet": { "openai": false, "anthropic": true, "gemini": false }
  }
}
  • mode"api" (a cloud provider key) or "local" (Ollama on your own infrastructure).
  • provider — the active cloud provider: "openai", "anthropic", or "gemini".
  • veilLevelVeil de-identification strictness: "full", "names", or "off".
  • apiKeySet — which providers have a stored key. The keys themselves are never returned.

Saving config

PUT accepts any subset of the fields above, plus an optional apiKey (plaintext) for the currently selected provider — it is encrypted before storage and used only to call the provider. Send "apiKey": "" to clear it.

curl -b cookies.txt -X PUT http://localhost:4000/api/ai/config \
  -H "Content-Type: application/json" \
  -d '{ "mode": "api", "provider": "anthropic", "apiKey": "sk-ant-…" }'

Testing connectivity

POST /api/ai/test does a lightweight probe before you rely on a setting: for local mode it pings Ollama's /api/tags; for API mode it confirms a key is stored (it does not spend a token).

curl -b cookies.txt -X POST http://localhost:4000/api/ai/test \
  -H "Content-Type: application/json" \
  -d '{ "mode": "local", "ollamaBaseUrl": "http://localhost:11434" }'

Importing records

POST /api/ai/import commits patient records the clinician approved in the chat import preview (see the chat agent). The body is { "records": [...] } of patient objects in temetro's patient shape. The server re-validates every record and writes via the audited patient service — the AI never writes to the database directly.

{
  "created": ["10293", "10294"],
  "failed": [{ "fileNumber": "10295", "error": "fileNumber: Required" }]
}

On this page