AiModel
Defines an AI model endpoint used by AI-assisted features such as the spam classifier and the Sieve llm_prompt function.
This object can be configured from the WebUI under Settings › AI
Fields
Section titled “Fields”AiModel is a multi-variant object: each instance has an @type discriminator selecting one of the variants below, and each variant carries its own set of fields.
@type: "OpenAi"
Section titled “@type: "OpenAi"”OpenAI compatible
profile
Section titled “profile”Type:
AiOpenAiProfile· default:"OpenAi"Server profile, which selects the token limit parameter, the structured output format and the authentication header
logprobs
Section titled “logprobs”Type:
Boolean· default:falseWhether to request token log probabilities and use them as the classifier confidence
maxOutputTokens
Section titled “maxOutputTokens”Type:
UnsignedInt· default:4096· min: 1 · max: 1000000Maximum number of tokens the model may generate, including reasoning tokens. The spam classifier uses its own smaller limit.
temperature
Section titled “temperature”Type:
Float?· min: 0 · max: 2Sampling temperature. When empty, the parameter is omitted and the provider default is used.
reasoning
Section titled “reasoning”Type:
AiReasoning· default:"Default"Reasoning effort requested from the model
extraParameters
Section titled “extraParameters”Type:
Text?JSON object whose members are merged into every request body
Type:
String· requiredShort name used to reference this model
Type:
String· requiredModel identifier sent to the provider
Type:
Uri?Base URL of the provider API. When empty, the provider’s default URL is used.
apiKey
Section titled “apiKey”Type:
SecretKeyOptional· default:{"@type":"None"}API key sent to the provider using its native authentication header
httpHeaders
Section titled “httpHeaders”Type:
Map<String, String>Additional headers to include in requests to the provider
allowInvalidCerts
Section titled “allowInvalidCerts”Type:
Boolean· default:falseWhether to accept invalid TLS certificates from the endpoint
timeout
Section titled “timeout”Type:
Duration· default:60000Maximum time to wait for a single response from the endpoint
maxConcurrentRequests
Section titled “maxConcurrentRequests”Type:
UnsignedInt· default:16· min: 1 · max: 4096Maximum number of requests sent to this model at the same time
rateLimit
Section titled “rateLimit”Type:
Rate?Maximum number of requests sent to this model within the rate period, spaced evenly. When empty, no rate limit is applied.
@type: "Anthropic"
Section titled “@type: "Anthropic"”Anthropic
maxOutputTokens
Section titled “maxOutputTokens”Type:
UnsignedInt· default:4096· min: 1 · max: 1000000Maximum number of tokens the model may generate, including reasoning tokens. The spam classifier uses its own smaller limit.
temperature
Section titled “temperature”Type:
Float?· min: 0 · max: 2Sampling temperature. When empty, the parameter is omitted and the provider default is used.
reasoning
Section titled “reasoning”Type:
AiReasoning· default:"Default"Reasoning effort requested from the model
extraParameters
Section titled “extraParameters”Type:
Text?JSON object whose members are merged into every request body
Type:
String· requiredShort name used to reference this model
Type:
String· requiredModel identifier sent to the provider
Type:
Uri?Base URL of the provider API. When empty, the provider’s default URL is used.
apiKey
Section titled “apiKey”Type:
SecretKeyOptional· default:{"@type":"None"}API key sent to the provider using its native authentication header
httpHeaders
Section titled “httpHeaders”Type:
Map<String, String>Additional headers to include in requests to the provider
allowInvalidCerts
Section titled “allowInvalidCerts”Type:
Boolean· default:falseWhether to accept invalid TLS certificates from the endpoint
timeout
Section titled “timeout”Type:
Duration· default:60000Maximum time to wait for a single response from the endpoint
maxConcurrentRequests
Section titled “maxConcurrentRequests”Type:
UnsignedInt· default:16· min: 1 · max: 4096Maximum number of requests sent to this model at the same time
rateLimit
Section titled “rateLimit”Type:
Rate?Maximum number of requests sent to this model within the rate period, spaced evenly. When empty, no rate limit is applied.
@type: "Gemini"
Section titled “@type: "Gemini"”Google Gemini
logprobs
Section titled “logprobs”Type:
Boolean· default:falseWhether to request token log probabilities and use them as the classifier confidence
maxOutputTokens
Section titled “maxOutputTokens”Type:
UnsignedInt· default:4096· min: 1 · max: 1000000Maximum number of tokens the model may generate, including reasoning tokens. The spam classifier uses its own smaller limit.
temperature
Section titled “temperature”Type:
Float?· min: 0 · max: 2Sampling temperature. When empty, the parameter is omitted and the provider default is used.
reasoning
Section titled “reasoning”Type:
AiReasoning· default:"Default"Reasoning effort requested from the model
extraParameters
Section titled “extraParameters”Type:
Text?JSON object whose members are merged into every request body
Type:
String· requiredShort name used to reference this model
Type:
String· requiredModel identifier sent to the provider
Type:
Uri?Base URL of the provider API. When empty, the provider’s default URL is used.
apiKey
Section titled “apiKey”Type:
SecretKeyOptional· default:{"@type":"None"}API key sent to the provider using its native authentication header
httpHeaders
Section titled “httpHeaders”Type:
Map<String, String>Additional headers to include in requests to the provider
allowInvalidCerts
Section titled “allowInvalidCerts”Type:
Boolean· default:falseWhether to accept invalid TLS certificates from the endpoint
timeout
Section titled “timeout”Type:
Duration· default:60000Maximum time to wait for a single response from the endpoint
maxConcurrentRequests
Section titled “maxConcurrentRequests”Type:
UnsignedInt· default:16· min: 1 · max: 4096Maximum number of requests sent to this model at the same time
rateLimit
Section titled “rateLimit”Type:
Rate?Maximum number of requests sent to this model within the rate period, spaced evenly. When empty, no rate limit is applied.
@type: "Ollama"
Section titled “@type: "Ollama"”Ollama
logprobs
Section titled “logprobs”Type:
Boolean· default:falseWhether to request token log probabilities and use them as the classifier confidence
keepAlive
Section titled “keepAlive”Type:
Duration?How long Ollama keeps the model loaded after a request. When empty, the server default is used.
maxOutputTokens
Section titled “maxOutputTokens”Type:
UnsignedInt· default:4096· min: 1 · max: 1000000Maximum number of tokens the model may generate, including reasoning tokens. The spam classifier uses its own smaller limit.
temperature
Section titled “temperature”Type:
Float?· min: 0 · max: 2Sampling temperature. When empty, the parameter is omitted and the provider default is used.
reasoning
Section titled “reasoning”Type:
AiReasoning· default:"Default"Reasoning effort requested from the model
extraParameters
Section titled “extraParameters”Type:
Text?JSON object whose members are merged into every request body
Type:
String· requiredShort name used to reference this model
Type:
String· requiredModel identifier sent to the provider
Type:
Uri?Base URL of the provider API. When empty, the provider’s default URL is used.
apiKey
Section titled “apiKey”Type:
SecretKeyOptional· default:{"@type":"None"}API key sent to the provider using its native authentication header
httpHeaders
Section titled “httpHeaders”Type:
Map<String, String>Additional headers to include in requests to the provider
allowInvalidCerts
Section titled “allowInvalidCerts”Type:
Boolean· default:falseWhether to accept invalid TLS certificates from the endpoint
timeout
Section titled “timeout”Type:
Duration· default:60000Maximum time to wait for a single response from the endpoint
maxConcurrentRequests
Section titled “maxConcurrentRequests”Type:
UnsignedInt· default:16· min: 1 · max: 4096Maximum number of requests sent to this model at the same time
rateLimit
Section titled “rateLimit”Type:
Rate?Maximum number of requests sent to this model within the rate period, spaced evenly. When empty, no rate limit is applied.
@type: "TypeSafe"
Section titled “@type: "TypeSafe"”TypeSafe
Type:
String· requiredShort name used to reference this model
Type:
String· requiredModel identifier sent to the provider
Type:
Uri?Base URL of the provider API. When empty, the provider’s default URL is used.
apiKey
Section titled “apiKey”Type:
SecretKeyOptional· default:{"@type":"None"}API key sent to the provider using its native authentication header
httpHeaders
Section titled “httpHeaders”Type:
Map<String, String>Additional headers to include in requests to the provider
allowInvalidCerts
Section titled “allowInvalidCerts”Type:
Boolean· default:falseWhether to accept invalid TLS certificates from the endpoint
timeout
Section titled “timeout”Type:
Duration· default:60000Maximum time to wait for a single response from the endpoint
maxConcurrentRequests
Section titled “maxConcurrentRequests”Type:
UnsignedInt· default:16· min: 1 · max: 4096Maximum number of requests sent to this model at the same time
rateLimit
Section titled “rateLimit”Type:
Rate?Maximum number of requests sent to this model within the rate period, spaced evenly. When empty, no rate limit is applied.
JMAP API
Section titled “JMAP API”The AiModel object is available via the urn:stalwart:jmap capability.
x:AiModel/get
Section titled “x:AiModel/get”This is a standard Foo/get method as defined in RFC 8620, Section 5.1.
This method requires the sysAiModelGet permission.
curl -X POST https://mail.example.com/jmap/ \ -H 'Authorization: Bearer $TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "methodCalls": [ [ "x:AiModel/get", { "ids": [ "id1" ] }, "c1" ] ], "using": [ "urn:ietf:params:jmap:core", "urn:stalwart:jmap" ] }'x:AiModel/set
Section titled “x:AiModel/set”This is a standard Foo/set method as defined in RFC 8620, Section 5.3.
Supports the following operations in a single call: create, update, destroy.
Create
Section titled “Create”This operation requires the sysAiModelCreate permission.
curl -X POST https://mail.example.com/jmap/ \ -H 'Authorization: Bearer $TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "methodCalls": [ [ "x:AiModel/set", { "create": { "new1": { "@type": "OpenAi", "apiKey": { "@type": "None" }, "httpHeaders": {}, "model": "Example", "name": "Example" } } }, "c1" ] ], "using": [ "urn:ietf:params:jmap:core", "urn:stalwart:jmap" ] }'Update
Section titled “Update”This operation requires the sysAiModelUpdate permission.
curl -X POST https://mail.example.com/jmap/ \ -H 'Authorization: Bearer $TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "methodCalls": [ [ "x:AiModel/set", { "update": { "id1": { "extraParameters": "updated value" } } }, "c1" ] ], "using": [ "urn:ietf:params:jmap:core", "urn:stalwart:jmap" ] }'Destroy
Section titled “Destroy”This operation requires the sysAiModelDestroy permission.
curl -X POST https://mail.example.com/jmap/ \ -H 'Authorization: Bearer $TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "methodCalls": [ [ "x:AiModel/set", { "destroy": [ "id1" ] }, "c1" ] ], "using": [ "urn:ietf:params:jmap:core", "urn:stalwart:jmap" ] }'x:AiModel/query
Section titled “x:AiModel/query”This is a standard Foo/query method as defined in RFC 8620, Section 5.5.
This method requires the sysAiModelQuery permission.
curl -X POST https://mail.example.com/jmap/ \ -H 'Authorization: Bearer $TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "methodCalls": [ [ "x:AiModel/query", { "filter": {} }, "c1" ] ], "using": [ "urn:ietf:params:jmap:core", "urn:stalwart:jmap" ] }'stalwart-cli wraps the same JMAP calls. See the CLI reference for installation, authentication, and general usage.
stalwart-cli get AiModel id1Create
Section titled “Create”stalwart-cli create AiModel/OpenAi \ --field name=Example \ --field model=Example \ --field 'apiKey={"@type":"None"}' \ --field 'httpHeaders={}'stalwart-cli query AiModelUpdate
Section titled “Update”stalwart-cli update AiModel id1 --field extraParameters='updated value'Delete
Section titled “Delete”stalwart-cli delete AiModel --ids id1Nested types
Section titled “Nested types”SecretKeyOptional
Section titled “SecretKeyOptional”An optional secret value, or none.
None: No secret. No additional fields.Value: Secret value. Carries the fields ofSecretKeyValue.EnvironmentVariable: Secret read from environment variable. Carries the fields ofSecretKeyEnvironmentVariable.File: Secret read from file. Carries the fields ofSecretKeyFile.
SecretKeyValue
Section titled “SecretKeyValue”A secret value provided directly.
secret
Section titled “secret”Type:
String· required · secretPassword or secret value
SecretKeyEnvironmentVariable
Section titled “SecretKeyEnvironmentVariable”A secret value read from an environment variable.
variableName
Section titled “variableName”Type:
String· requiredEnvironment variable name to read the secret from
SecretKeyFile
Section titled “SecretKeyFile”A secret value read from a file.
filePath
Section titled “filePath”Type:
String· requiredFile path to read the secret from
Defines a rate limit as a count over a time period.
Type:
UnsignedInt· default:0· min: 1 · max: 1000000Count
period
Section titled “period”Type:
Duration· default:0· min: 1Period
AiOpenAiProfile
Section titled “AiOpenAiProfile”| Value | Label |
|---|---|
OpenAi | OpenAI |
Azure | Azure OpenAI |
Vllm | vLLM |
LlamaCpp | llama.cpp |
Generic | Generic |
AiReasoning
Section titled “AiReasoning”| Value | Label |
|---|---|
Default | Provider default |
Off | Off |
Low | Low |
Medium | Medium |
High | High |