Documentation menu

Insights

AI-generated activity summaries, top error patterns, and AI digest delivery config.

These endpoints have no plain /api/insights path — they’re only mounted org/project-scoped, at /api/orgs/:orgSlug/projects/:projectSlug/insights.

Auth: session cookie (or API key, resolved to your account’s org/project membership) — see Authentication

POST /api/orgs/:orgSlug/projects/:projectSlug/insights/summary

Generate a fresh AI summary of recent log activity for a time window and persist it (becomes the result of GET .../insights/summary until the next one is generated).

Request body

fieldtyperequireddescription
minutesnumbernoTime window: 5 | 15 | 30 | 60. Any other value (or omitted) silently falls back to 15

Response 200

{
  "id": "01hxyz...",
  "summary_text": "Error rate spiked in checkout-api due to repeated timeouts...",
  "error_count": 12,
  "warn_count": 4,
  "event_count": 340,
  "created_at": 1720478400000,
  "time_window_minutes": 15
}

Errors:

  • 503{ "error": "AI not available" } if the AI binding isn’t configured for this environment
  • 402{ "error": "usage_limit_exceeded", "message": "Monthly AI summary limit reached. Upgrade your plan." } if the org has hit its monthly AI-summary quota. Unlike most session-authed endpoints, this one does enforce a 402 — it’s the exception to the usual “402 doesn’t apply to query/management endpoints” rule (billing-DB errors while checking the quota are swallowed and don’t block the request)

429 doesn’t apply — this route isn’t rate-limited.

GET /api/orgs/:orgSlug/projects/:projectSlug/insights/summary

Fetch the most recently generated summary, if any.

Response 200

{
  "summary": {
    "id": "01hxyz...",
    "summary_text": "Error rate spiked in checkout-api due to repeated timeouts...",
    "error_count": 12,
    "warn_count": 4,
    "event_count": 340,
    "created_at": 1720478400000,
    "time_window_minutes": 15
  }
}

summary is null if no summary has ever been generated for this project.

GET /api/orgs/:orgSlug/projects/:projectSlug/insights/patterns

List known message patterns (from the pattern registry), ranked by total occurrence count.

Query params

paramtypedescription
limitnumberMax results. Default 50, capped at 200
levelstringExact match on level. Omit, or pass all, for no filter
servicestringExact match on service. Omit, or pass all, for no filter

Response 200

{
  "patterns": [
    {
      "id": "pat_01hxyz",
      "normalized_message": "Timeout connecting to {service}",
      "level": "error",
      "service": "checkout-api",
      "first_seen": 1720392000000,
      "last_seen": 1720478390000,
      "occurrence_count": 88,
      "is_new": false
    }
  ]
}

is_new is computed at request time — true if first_seen is within the last hour.

GET /api/orgs/:orgSlug/projects/:projectSlug/insights/digest-config

Fetch the project’s AI digest delivery configuration (used by the periodic AI-digest cron to push summaries to a webhook or email).

Response 200

{
  "config": {
    "project_id": "proj_01abc",
    "webhook_url": "https://discord.com/api/webhooks/...",
    "notify_email": null,
    "enabled": true
  }
}

config is null if no digest config has been saved for this project yet.

PUT /api/orgs/:orgSlug/projects/:projectSlug/insights/digest-config

Create or replace the project’s AI digest delivery configuration.

Request body

fieldtyperequireddescription
webhook_urlstringconditionalDelivery webhook. Discord webhook URLs are auto-detected and delivered as a rich embed; any other URL receives the raw digest as JSON
notify_emailstringconditionalDelivery email address
enabledbooleannoDefaults to true. If true (or omitted), at least one of webhook_url/notify_email is required

Response 200

{
  "config": {
    "project_id": "proj_01abc",
    "webhook_url": "https://discord.com/api/webhooks/...",
    "notify_email": null,
    "enabled": true
  }
}

Errors: 400{ "error": "At least one of webhook_url or notify_email is required when enabled" }

Common responses (401; 402 and 429 don’t apply to these endpoints, except POST .../insights/summary which can return 402 as described above) — see Authentication.