Lua/Honeycomb

Insights & Digest

Honeycomb's proactive layer — mined contradictions, converging themes, dropped commitments, and automation opportunities, plus the per-person digest and agent recommendations built on top.

Ask and Search answer the questions you think to ask. Insights surface what your organization should know but never queried: a new fact that quietly contradicts a standing one, a commitment whose due date slipped past unnoticed, three people independently hitting the same wall, a manual workflow an agent could take over. Honeycomb mines your memory continuously, and every insight arrives with its receipts — the exact memories that justify it.

At a glance

  • Four insight typescontradiction, automation_opportunity, convergence, and stale_commitment — each grounded in evidence memories and the people involved.
  • Generated continuously. Contradictions are checked the moment new memory lands; the other detectors sweep your corpus in the background. Trigger a fresh run anytime with POST /api/v1/insights/mine.
  • A simple lifecycle. Insights arrive as new; you acknowledge or dismiss them via PATCH /api/v1/insights/:id. Dismissing with a reason teaches the miner what not to resurface.
  • Close the loop. Every automation opportunity can generate a paste-ready agent spec (POST /api/v1/insights/:id/agent-prompt), and GET /api/v1/agents/recommended reshapes the feed into "agents your org should build."
  • The DigestGET /api/v1/digest — is the rollup: the top insights for your whole organization, or for one person when you act on their behalf.
  • In the console, the Insights and Opportunities pages give your team the same feed with one-click review.

What counts as an insight

Honeycomb is deliberately conservative. An insight only surfaces when it clears a real bar — confident, business-relevant, and evidenced. Office logistics, restatements of known facts, and one-off events don't page you.

TypeWhat it flagsExample
contradictionTwo facts in your memory that can't both be true — including a decision that quietly reversedStanding memory says the Meridian renewal closes March 1; a new note says it slipped to Q3
automation_opportunityA recurring manual workflow, missed SLA, scheduled deliverable, or bottleneck an agent could take overSomeone compiles the support quality report by hand every Friday
convergenceThree or more people independently raising the same themeSales, support, and onboarding all flag enterprise onboarding delays in the same month
stale_commitmentA specific person promised a specific action by a date that has now passed, with no follow-up"Daniel will send the revised MSA by June 20" — and nothing since

Automation opportunities additionally carry a signalType describing why they were flagged:

signalTypeMeaning
recurring_toilA repetitive manual task — report compilation, triage, data entry, drafting, scheduling
sla_gapA stated metric below target that an agent could close — response times, growing backlogs
periodicA recurring scheduled deliverable — the Friday status report, the monthly board deck
pain_bottleneckPeople chasing, waiting, or blocked — approval chasing, manual reconciliation

Every insight carries its receipts

An insight is never a hunch. Each one links the memories that justify it (evidenceMemoryIds), the original source records behind those memories (evidenceEntryIds), and the people involved (people). Insights also respect Spaces: an insight inherits the most restrictive audience of its evidence, so a conclusion drawn from a private memory is never visible to someone who couldn't see that memory.

Note: memories marked personal never contribute to insights. The miner only reads organization-shareable memory.

How insights are generated

Two paths feed the same feed:

  1. Real-time. Every new memory is checked against standing facts about the same entities as it lands. A confident, business-critical conflict becomes a contradiction insight immediately — not at the next sweep.
  2. Background sweeps. The pattern detectors (opportunities, convergence, stale commitments, plus a contradiction re-scan) need a cross-corpus view, so they run periodically over your whole memory store.

All results funnel through a dedup layer: re-mining an unchanged corpus never duplicates an insight, and anything a human dismissed stays suppressed (see the lifecycle for the exception).

Trigger a run yourself

POST /api/v1/insights/mine runs all detectors on demand and returns the insights produced by that run. It operates at organization scope with your API key.

curl -s -X POST "$HONEYCOMB_URL/api/v1/insights/mine" \
  -H "Authorization: Bearer hck_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Optionally pass { "namespace": "sales" } to scope the run to one namespace.

Note: a mining run analyzes your corpus in depth, so it can take a minute or more on a large memory store. It's idempotent — running it twice back-to-back won't flood your feed.

Reading the feed: GET /api/v1/insights

ParamDefaultNotes
statusallnew, acknowledged, dismissed
typeallOne of the four types above
limit50Max results, ranked by score then recency
evidencefalsetrue hydrates the full text of each evidence memory
curl -s "$HONEYCOMB_URL/api/v1/insights?status=new&evidence=true&limit=2" \
  -H "Authorization: Bearer hck_..."
{
  "insights": [
    {
      "id": "ins_84",
      "type": "automation_opportunity",
      "signalType": "periodic",
      "title": "Weekly support quality report is compiled by hand",
      "body": "Priya compiles ticket stats and CSAT into a Friday report manually each week. (Impact: ~3 hours weekly)",
      "score": 0.81,
      "people": ["Priya Shah"],
      "evidenceMemoryIds": ["m_118", "m_131", "m_140", "m_152"],
      "evidenceEntryIds": ["ke_61", "ke_67"],
      "evidence": [
        { "id": "m_118", "content": "Priya spent Friday afternoon compiling the weekly support quality report again..." },
        { "id": "m_131", "content": "Support review: Priya pulled CSAT and first-response numbers into the deck by hand..." }
      ]
    },
    {
      "id": "ins_91",
      "type": "stale_commitment",
      "title": "Dropped commitment: send the revised MSA to Meridian legal",
      "body": "Daniel Okafor — due 2026-06-20, no follow-up found.",
      "score": 0.74,
      "people": ["Daniel Okafor"],
      "evidenceMemoryIds": ["m_203"],
      "evidenceEntryIds": []
    }
  ]
}

Field notes:

  • score is a 0–1 notability rating; the feed is ordered by it.
  • signalType appears only on automation_opportunity insights.
  • evidenceEntryIds can be empty for convergence and stale_commitment insights, which resolve memories rather than source entries.
  • With evidence=true, hydration is permission-aware: evidence memories the caller can't see are omitted entirely — not even their ids leak. Add x-acting-user to read the feed as a specific person; results narrow to insights in Spaces they can see.

The lifecycle

Insights arrive as new — that's the default feed. You move them on with PATCH /api/v1/insights/:id (organization scope):

curl -s -X PATCH "$HONEYCOMB_URL/api/v1/insights/ins_84" \
  -H "Authorization: Bearer hck_..." \
  -H "Content-Type: application/json" \
  -d '{ "status": "dismissed", "reason": "wrong_team" }'

Returns { "ok": true }. status must be acknowledged or dismissed — anything else is a 400. The system may also set archived on lower-scoring insights when the feed is full; archived insights come back automatically if a later run re-confirms them.

Dismiss with a reason

The reason you pass on dismissal drives what the miner does next time it finds the same thing:

ReasonMeaningCan it resurface?
wrong_teamReal, but not this team's to act onYes — on a later run
cant_actReal, but not actionable yetYes — on a later run
not_toilNot actually a problem worth automatingNo — suppressed permanently
already_automatedAn agent already handles thisNo — suppressed permanently
(none)A bare "no"No — suppressed permanently

Warning: dismissing without a reason is a permanent "no" — that concept won't resurface even if fresh evidence accumulates. If the insight is real but just not yours to handle, dismiss with wrong_team or cant_act so it can come back when circumstances change.

Acknowledging clears any previous dismiss reason, so a later re-dismissal must state its reason again.

Acting on an insight

Generate an agent prompt

Every insight — most usefully an automation opportunity — can be turned into a paste-ready agent specification, grounded strictly in the insight's own evidence (no invented metrics, tools, or systems):

curl -s -X POST "$HONEYCOMB_URL/api/v1/insights/ins_84/agent-prompt" \
  -H "Authorization: Bearer hck_..."
{
  "prompt": "Goal: Compile and distribute the weekly support quality report without manual effort.\nTrigger: Every Friday at 09:00.\nSteps: 1. Pull the week's ticket volume, first-response time, and CSAT...\nInputs: Support ticket data, CSAT survey results.\nOutput: A formatted report posted to the support channel.\nGuardrails: Flag for human review if any metric moves more than 20% week over week."
}

Paste the spec into your agent-building workflow — Honeycomb doesn't provision anything itself. Once the agent exists, it can read and write the same organizational memory through the six MCP tools (honeycomb_search, honeycomb_recall, honeycomb_context, honeycomb_ingest, honeycomb_upload, honeycomb_manage) — see Agents & MCP. Unknown insight ids return 404. This endpoint reads the insight's evidence, so it honors x-acting-user scoping just like GET /insights.

A recommendation-shaped view of the opportunity feed — "the agents your organization should consider building." Params: limit (default 20, max 100) and an optional signalType filter.

curl -s "$HONEYCOMB_URL/api/v1/agents/recommended?signalType=recurring_toil" \
  -H "Authorization: Bearer hck_..."
{
  "agents": [
    {
      "id": "ins_84",
      "name": "Weekly support quality report is compiled by hand",
      "signalType": "recurring_toil",
      "rationale": "Priya compiles ticket stats and CSAT into a Friday report manually each week. (Impact: ~3 hours weekly)",
      "score": 0.81,
      "evidenceCount": 4,
      "people": ["Priya Shah"]
    }
  ]
}

Each id is an insight id — feed it straight to the agent-prompt endpoint above. Run POST /insights/mine first if you want the freshest possible list.

The Digest: GET /api/v1/digest

The digest is the periodic rollup — the ranked top of the active insight feed, ready to drop into a daily brief, a team channel, or a morning email. It has two modes:

  • Organization briefing. Called with just your API key, it returns the top limit (default 10) active insights across your whole organization.
  • Personal digest. Add x-acting-user and it narrows to insights that name that person — their dropped commitments, contradictions in their deals, opportunities in their toil.
curl -s "$HONEYCOMB_URL/api/v1/digest?limit=5" \
  -H "Authorization: Bearer hck_..." \
  -H "x-acting-user: [email protected]"
{
  "digest": [
    {
      "id": "ins_84",
      "type": "automation_opportunity",
      "signalType": "periodic",
      "title": "Weekly support quality report is compiled by hand",
      "body": "Priya compiles ticket stats and CSAT into a Friday report manually each week. (Impact: ~3 hours weekly)",
      "score": 0.81,
      "people": ["Priya Shah"],
      "evidenceMemoryIds": ["m_118", "m_131", "m_140", "m_152"],
      "evidenceEntryIds": ["ke_61", "ke_67"]
    }
  ]
}

Records have the same shape as GET /insights (without evidence hydration). Person matching uses the identity graph — email addresses, chat handles, and names all resolve to the same person — so x-acting-user: [email protected] finds insights naming "Priya Shah."

In the console

Your team can work the same feed without touching the API — see Console for a full tour:

  • Insights — the full feed across all four types, with filter chips by type, evidence for each insight, a Mine insights button to trigger a fresh run, and one-click acknowledge / dismiss.
  • Opportunities — the automation-opportunity view: mined agent candidates with their signal types and evidence counts, plus a Mine the corpus action.

Troubleshooting an empty feed

GET /api/v1/insights/status (organization scope) tells you whether mining is healthy — distinguishing "mining hasn't run yet" from "mining ran and found nothing":

{
  "enabled": true,
  "insights": { "total": 62, "new": 17, "byType": { "automation_opportunity": 41, "contradiction": 12, "convergence": 5, "stale_commitment": 4 } },
  "lastInsightAt": "2026-07-07T09:14:00.000Z",
  "miningEnabled": true
}
  • insights.total is 0 and lastInsightAt is null — mining hasn't produced anything yet. If you just started ingesting, give the background sweep a cycle, or trigger POST /insights/mine yourself. Insights need a real corpus; a handful of memories won't clear the evidence bars.
  • total is high but new is 0 — everything has been reviewed. That's success, not a bug.
  • Insights exist but your read comes back empty — check Space scoping: if you're calling with x-acting-user, that person may not have visibility into the Spaces the insights inherited. See Spaces & Permissions.

Next steps

  • Ask — question-answering over the same memory the miner reads.
  • Agents & MCP — wire up the agent you just spec'd from an opportunity.
  • Spaces & Permissions — how insight visibility follows evidence visibility.
  • API Reference — every endpoint on this page, in one place.
Insights & Digest — Honeycomb Docs