Source: https://help.spamfoo.com/api/integration-info
Last updated: 2026-10-27

***

# 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/info`

## When 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](https://help.spamfoo.com/api#authentication).

## 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](https://help.spamfoo.com/api#versioning). |
| `clientVersion` | string | The SpamFoo Client version. |
| `mode` | string | `standalone` or `embedded`. See [Mode](https://help.spamfoo.com/guides/configure#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](https://help.spamfoo.com/api/integration-info#license). |
| `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](https://help.spamfoo.com/guides/corrections#automatic-reports). |
| `capabilities` | array of strings | Optional features this SpamFoo Client supports: `boundary` and `auth-results` ([Share Your Authentication Results](https://help.spamfoo.com/api/classify#boundary)), `priority` ([Mark Bulk Work](https://help.spamfoo.com/api/classify#priority)), `caller-identity` (the `X-SpamFoo-Caller` header), `login-links` ([Create a Sign-In Link](https://help.spamfoo.com/api/login-link)), and `address-map` ([Push an Address Map](https://help.spamfoo.com/api/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](https://help.spamfoo.com/api#blocked). |

## Example

### curl

```
curl -s http://localhost:16253/integration/info \
    -H "X-SpamFoo-Proxy-Auth: $SPAMFOO_PROXY_SECRET"
```

### C#

```
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")}");
```

### Python

```
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']}")
```
