Integration health: one board for every connection
Once a product is wired in — domains, reader sign-in, consent, the rights executor, connectors, a status heartbeat, webhooks — each piece can break on its own, and each has its own panel. GET /orgs/{orgId}/integration-health reads all of them at once and says, for each, whether it works and what to do if it does not. Every link a check's docs field gives lands on the guide for that piece; this page is the one docs names for the board itself.
curl -s -H "Authorization: Bearer $FORUMULATE_TOKEN" \
-H "Forumulate-Version: 2027-03-01" \
https://forumulate.com/api/orgs/yourproduct/integration-health |
jq -r '.checks[] | select(.ok == false) | "\(.id): \(.fix)"'The organization is its slug or its id. The same answer is at GET /v1/integration-health?org=<slug-or-id>, the address our other products answer too, so a console that polls several of them uses one shape.
The answer
{
"checks": [
{ "id": "domains.served", "ok": true, "detail": "…", "fix": "…", "docs": "https://forumulate.com/guides/custom-domains" },
{ "id": "consent.webhook_verified", "ok": false, "detail": "…", "fix": "…", "docs": "…", "hop": "auth" }
],
"generatedAt": "2026-10-30T09:00:00.000Z"
}Field | Meaning |
|---|---|
| Stable name of the check (list below). |
|
|
| What was seen, in a sentence or two. Never a secret or a full webhook URL. |
| One sentence saying what to do. |
| The guide for that piece. |
| For a check that walks a path, where it broke: |
|
|
The checks always come in this order:
| What it looks at |
|---|---|
| Every custom domain is verified, active and answering (up to five live domains are probed). |
| Reader sign-in is set up; an OIDC issuer's discovery document is fetched (up to three). |
| Your consent platform's webhook has been received and its signature verified. |
| The signed identity that ties a reader on your product to the same person on your pages. |
| The privacy-request executor is enabled and its key is in use. |
| Each public space's sitemap is served. |
| Canonical links name your address, not ours. |
| One per connector that reads a space as knowledge ( |
| API tokens, integration tokens and partner links that expire within 14 days — a warning, never |
| Your heartbeat monitors have pinged recently. |
| No outgoing webhook is failing. |
| The last outside check of your site (see |
A provider whose only credentials are revoked integration tokens is not a knowledge consumer and gets no connectors.<provider>.kb_read row: revoking is how you retire one. An installed connector stays on the board, so a connector whose tokens are all expired or revoked still fails at auth.
Credentials expiring
credentials.expiring names every key that still works but stops within 14 days, soonest first: integration tokens and partner links of the organization, and the API tokens that can act on it (members' and service accounts' tokens not confined to another organization, and delivery keys confined to this one). A personal access token created without expiresInDays lives 90 days; an integration token at most a year. It is a warning (ok: true, warning: true), because nothing is broken yet. With nothing expiring it is ok: null.
You do not have to poll for it. Once per token, 14 days before it expires, we send pat.expiring or integration_token.expiring to your webhooks and e-mail the owner: a personal token's owner; for an integration token, whoever minted it (the organization's owners when that person has left); for a service-account token or a delivery key, the owners.
Nothing is written. The board reads what is stored; only live custom domains and OIDC discovery are fetched, through the same guarded fetcher every outbound call uses.
Who may read it
A token with the read scope, held by someone with org.manage_integrations, or a partner link holding health:read for this organization — see Partner links and token exchange. A partner link for another organization gets 403 wrong_organization; other integration tokens get wrong_audience.
When to read it
After
forumulate apply, and after each manual step it lists (a DNS record, a proxy rule), until every check you configured istrue.After a deploy of your product: a changed proxy rule or a rotated secret shows here before a reader notices.
From your own monitoring, on a schedule.
The board does not suggest changes. One suggestion lives elsewhere: GET /orgs/{orgId}/reader-auth and the manifest plan answer recommendations, which holds reader_auth.use_atlas for an organization that uses Atlas but signs readers in another way (see Putting a product on Forumulate).
In the API
Every operation below is also reachable from the other surfaces without a dedicated command. forumulate api <Operation> calls it from the CLI, the JavaScript SDK has a typed method for each one (the last column names it; the Python and Go SDKs are generated from the same spec), and an agent reaches the organization-scoped ones through the MCP agent server — its api_* family tools, or call_api. Where a CLI command or a hand-made MCP tool exists too, the last column names it. Operation names link to the API reference.
Suite Integration Health
Operation | Request | What it does | Shortcuts |
|---|---|---|---|
| Check an organization’s integrations ( |
|