AI insights
Two endpoints. Read the current insights payload, or trigger a regeneration. Both are gated by plan and ability.
Base URL: https://formspring.io/api/v1
| Method | Path | Ability |
|---|---|---|
| GET | /ai-insights |
insights:read |
| POST | /ai-insights/regenerate |
insights:write |
For the conceptual overview, see AI insights →.
Read insights
GET /ai-insights
Returns the most recent generated insights for the active team. Insights are produced once a week by a scheduled job and cached. Reading is cheap.
Response 200:
{
"data": {
"generated_at": "2026-05-05T09:00:00Z",
"period_start": "2026-04-28T00:00:00Z",
"period_end": "2026-05-05T00:00:00Z",
"submissions_total": 230,
"delta_vs_prior_week": 0.18,
"themes": [
{ "label": "Export feature questions", "count": 41 },
{ "label": "Pricing inquiries", "count": 28 }
],
"categories": [
{ "name": "support", "count": 142 },
{ "name": "sales", "count": 47 },
{ "name": "spam", "count": 18 }
],
"score_distribution": {
"0.0-0.3": 198,
"0.3-0.6": 14,
"0.6-0.85": 9,
"0.85-1.0": 9
},
"summary_md": "Last week 230 submissions, up 18% vs prior week. Support volume dominated, mostly questions about the new CSV export. A burst of 9 spam submissions came from a single IP range and was caught by AI moderation.",
"spam_reasons": [
{ "reason": "ai_moderation", "count": 9 },
{ "reason": "honeypot_filled", "count": 6 },
{ "reason": "rate_limited", "count": 3 }
]
}
}
If insights have never been generated for this team (e.g. fresh signup), the response is 200 with data: null. Trigger a regeneration to produce the first run.
Status codes
| Status | Meaning |
|---|---|
200 |
Insights returned |
401 |
Token missing or invalid |
403 |
Token lacks insights:read |
423 |
Plan does not include AI features (free / starter / pro) — upgrade to Pro+ |
Trigger a regeneration
POST /ai-insights/regenerate
Queues a regeneration job for the current team's insights and weekly digest. Returns immediately; the job runs in the background.
The endpoint is idempotency-locked for 5 minutes. A second call within the lock window returns 409 Conflict instead of queueing a duplicate.
Response 202:
{ "ok": true, "queued_at": "2026-05-07T11:23:00Z" }
Status codes for regenerate
| Status | Meaning |
|---|---|
202 |
Regeneration queued |
401 |
Token missing or invalid |
403 |
Token lacks insights:write |
409 |
Already running (idempotency lock active) |
423 |
Plan does not include AI features |
A 409 response includes the lock's expiry so you know when you can retry:
{ "error": "already_running", "retry_after": 217 }
retry_after is in seconds.
Polling for completion
The regeneration endpoint returns 202 and doesn't block. To know when the new insights are ready:
- Poll
GET /ai-insightsand comparegenerated_at. - Or watch for the
ai-insights.regeneratedwebhook event on a configured webhook.
A typical regeneration takes 15–60 seconds depending on submission volume.
Triggering from MCP
The MCP server exposes the same action as the regenerate_ai_insights tool. The tool returns the same status codes and respects the same 5-minute idempotency lock.