Get Integration Info
Read the version, mode, license status, and limits of a SpamFoo Client. A mail server can call it when it connects, to check the proxy secret and adjust to the client it found.
GET
/integration/infoWhen to Use It
- Check that your proxy secret works before you send mail.
- Find the largest message SpamFoo Client accepts, so you can skip larger ones.
- Find out which optional features this SpamFoo Client supports, from
capabilities. - See whether the license is active, in a grace period, or not set up.
Request
No body or query parameters. Send the proxy secret in X-SpamFoo-Proxy-Auth, even from loopback. See Authenticate Requests.
Response
{
"contract": 1,
"clientVersion": "1.2.3",
"mode": "standalone",
"installKind": "package",
"license": {
"token": "...",
"reason": null,
"planCode": "...",
"planName": "...",
"status": "Active",
"expiresAt": "2027-10-01T00:00:00+00:00",
"tokenExpiresAt": "2026-10-28T14:00:00+00:00",
"graceEndsAt": null,
"lastHandshakeAt": "2026-10-13T14:00:00+00:00"
},
"maxBodyBytes": 67108864,
"publicUrlSet": false,
"autoSendTraining": false,
"capabilities": ["boundary", "auth-results", "priority", "caller-identity", "login-links", "address-map"]
}
| Field | Type | Description |
|---|---|---|
contract |
integer | The API version. See Versioning. |
clientVersion |
string | The SpamFoo Client version. |
mode |
string | standalone or embedded. See Mode. |
installKind |
string | package, container, portable (an archive), or sidecar. Embedded mode always reports sidecar. |
license |
object | The result of SpamFoo Client's last license check. See License Fields. |
maxBodyBytes |
integer | The largest message SpamFoo Client accepts, in bytes. Larger messages get 413. |
publicUrlSet |
boolean | true when an administrator set SPAMFOO_PUBLIC_URL, so sign-in links point to a fixed address. |
autoSendTraining |
boolean | Whether automatic training reports are turned on. See Automatic Training Reports. |
capabilities |
array of strings | Optional features this SpamFoo Client supports: boundary and auth-results (Share Your Authentication Results), priority (Mark Bulk Work), caller-identity (the X-SpamFoo-Caller header), login-links (Create a Sign-In Link), and address-map (Push an Address Map). |
License Fields
SpamFoo Client keeps the result of its last license check in memory. After a restart, the fields are empty until the next check succeeds.
| Field | Type | Description |
|---|---|---|
token |
string or null | The signed license token from SpamFoo's last license check. It doesn't contain the license key. |
reason |
string or null | Why token is empty: not_activated (no license key) or no_handshake_yet (the license hasn't been checked since SpamFoo Client started). null when there is a token. |
planCode, planName |
string or null | The license's plan. |
status |
string or null | The license status, such as Active, Trial, or Grace (expired, but still working for a short time). |
expiresAt |
date and time or null | When the license expires. |
tokenExpiresAt |
date and time or null | When the token expires. In standalone mode, SpamFoo Client stops classifying mail at this time unless a new license check succeeds first. |
graceEndsAt |
date and time or null | When the grace period ends, while the license is in one. |
lastHandshakeAt |
date and time or null | When SpamFoo Client last checked the license with SpamFoo. |
Every field except token, reason, and lastHandshakeAt is null when token is null.
Errors
| Status | Body | Cause |
|---|---|---|
401 |
Empty | The proxy secret was missing or wrong. |
429 |
{"error": "...", "code": "auth_blocked"} |
Standalone mode only. Too many wrong secrets came from this address. See Repeated Wrong Secrets. |
Example
curl -s http://localhost:16253/integration/info \
-H "X-SpamFoo-Proxy-Auth: $SPAMFOO_PROXY_SECRET"
using System.Net.Http.Json;
using System.Text.Json;
var secret = Environment.GetEnvironmentVariable("SPAMFOO_PROXY_SECRET")
?? throw new InvalidOperationException("Set SPAMFOO_PROXY_SECRET.");
using var http = new HttpClient { BaseAddress = new Uri("http://localhost:16253") };
http.DefaultRequestHeaders.Add("X-SpamFoo-Proxy-Auth", secret);
var info = await http.GetFromJsonAsync<JsonElement>("/integration/info");
Console.WriteLine($"mode={info.GetProperty("mode")} maxBodyBytes={info.GetProperty("maxBodyBytes")}");
import os
import requests
response = requests.get(
"http://localhost:16253/integration/info",
headers={"X-SpamFoo-Proxy-Auth": os.environ["SPAMFOO_PROXY_SECRET"]},
timeout=10,
)
response.raise_for_status()
info = response.json()
print(f"mode={info['mode']} maxBodyBytes={info['maxBodyBytes']}")