Lua/Honeycomb

Asking Questions

Get grounded, cited answers from your organization's memory with POST /api/v1/ask — scoping, confidence, graded refusal, and the console Ask page.

POST /api/v1/ask is Honeycomb's flagship read path for humans. You send a natural-language question; Honeycomb finds the relevant evidence in your organization's memory and returns an answer where every claim is backed by an inline [n] citation pointing at a real source — or a clean refusal when the answer genuinely isn't on record.

At a glance

  • One endpoint, one callPOST /api/v1/ask with { "query": "..." } returns a complete answer as a single JSON body.
  • Every claim is cited — inline [n] markers in the answer map to entries in the results array, so you can always check the receipts.
  • Refusal over hallucination — if the evidence isn't there, Honeycomb says I don't have that information. instead of guessing, and tells you what is on record.
  • Scope it down — ask across everything you can see, or pin the question to one Space or one conversation.
  • Tune speed vs. care — the effort field trades latency for answer thoroughness.
  • No code required — the same engine powers the Ask page in the console.

How Honeycomb answers

The engine is bound by a strict grounding contract: it may only answer from evidence retrieved out of your organization's memory, within the Spaces the caller is allowed to see. It never fills gaps with general world knowledge. If two sources disagree, the answer reports both values rather than silently picking one.

Note: /ask returns one complete JSON body — there is no streaming. Thorough answers to complex questions can take tens of seconds, so set client timeouts to at least 60 seconds.

Your first question

All examples use $HONEYCOMB_URL for your workspace's API base URL and an API key with the hck_ prefix. See the Quickstart for getting both.

curl -s "$HONEYCOMB_URL/api/v1/ask" \
  -H "Authorization: Bearer hck_live_9f3ab2..." \
  -H "Content-Type: application/json" \
  -d '{ "query": "What is the renewal value of the Northwind contract?" }'
{
  "answer": "The Northwind renewal is worth **$1.8M** over a two-year term [2].",
  "answered": true,
  "confidence": 0.67,
  "citedIndices": [2],
  "results": [
    {
      "id": "res_01j9x4",
      "knowledgeEntryId": "ke_82ma1c",
      "score": 0.81,
      "content": "Northwind kickoff recap — legal review of the renewal paperwork starts next week...",
      "title": "Northwind kickoff notes",
      "namespace": "sales",
      "contentType": "meeting_notes",
      "sourceAgent": "notetaker",
      "tags": ["account:northwind"],
      "validFrom": "2026-05-02T00:00:00.000Z",
      "sourceChannel": "#sales"
    },
    {
      "id": "res_01j9x5",
      "knowledgeEntryId": "ke_91bd0f",
      "score": 0.78,
      "content": "Northwind renewal signed: $1.8M total contract value across the two-year term.",
      "title": "Northwind renewal signed",
      "namespace": "sales",
      "contentType": "message",
      "sourceAgent": "slack-sync",
      "tags": ["account:northwind"],
      "validFrom": "2026-06-11T00:00:00.000Z",
      "sourceChannel": "#deals"
    }
  ],
  "family": "single_hop",
  "coragExpanded": false,
  "mode": "hybrid",
  "searchTimeMs": 812
}

The [2] in the answer points at the second entry in results — citations are 1-based positions in that array. results always contains the full evidence set the engine read, in the order it saw it, so [n] resolves to results[n - 1].

Request reference

Headers

HeaderValueNotes
AuthorizationBearer hck_...Required. Your organization's API key.
Content-Typeapplication/jsonRequired.
x-acting-userA user's emailOptional. Ask as that person: first-person questions ("my open items") resolve to them, and answers only draw on memory they're allowed to see. Requires a key with acting-user permission.

Body fields

Only query is required. Everything else refines the ask.

FieldTypeDefaultWhat it does
querystring, 1–10000 charsrequiredYour question, in plain language.
effortlow medium highmediumSpeed vs. thoroughness — see Choosing an effort level.
limitint, 1–20010Maximum evidence items retrieved for the answer.
asOfISO date stringnowAnchors the reader's sense of "today" — useful for questions about a past state.
modehybrid semantic keyword graph temporalhybridRetrieval flavor. The default is right for almost all questions.
scope.spaceIdstringAnswer only from one Space's records.
scope.threadIdstringAnswer only from one conversation.
scope.namespacestring or string arrayRestrict to a namespace, e.g. "sales".
scope.sourcestring or string arrayRestrict by source platform, e.g. "slack".
scope.sourceChannelstring or string arrayRestrict by channel, e.g. "#engineering".
scope.contentTypestring or string arrayRestrict by record type, e.g. "meeting_notes".
scope.agentsstring or string arrayRestrict by the agent that wrote the memory.
scope.tagsstring arrayAll listed tags must match.
scope.dateRangeobject with from / to ISO datesOnly consider records in the window.

More retrieval-tuning knobs (rerank, scoreThreshold, exhaustive) are shared with search and documented in Search and Recall.

Reading the response

FieldTypeMeaning
answerstringThe answer in Markdown, with inline [n] citations — or the refusal text.
answeredbooleantrue when Honeycomb actually answered. false on refusal or when nothing relevant was found.
confidencenumber0 on refusal; otherwise starts at 0.55 and grows with each distinct cited source, capped at 0.95. It measures citation corroboration, not retrieval score.
citedIndicesnumber arrayThe [n] markers actually used in the answer (1-based, deduplicated).
resultsarrayThe full evidence set, in reading order. Each item includes content, title, namespace, contentType, sourceChannel, tags, dates, and a relevance score.
familystringThe engine's read on the question type (factual, timeline, profile, and so on). Useful for analytics; safe to ignore.
coragExpandedbooleantrue when the engine ran extra follow-up retrieval to fill evidence gaps for a multi-part question.
modestringThe retrieval mode that ran.
searchTimeMsnumberTime spent finding evidence.

Warning: Programmatically, always branch on the answered boolean — never string-match the answer text. A graded refusal still contains useful prose, but answered stays false.

Refusal is a feature

Most question-answering systems fail dangerously: when the evidence is missing, they improvise. Honeycomb's reader is only allowed to answer from retrieved evidence, so a missing fact produces the exact string I don't have that information. — and answered: false, confidence: 0.

That refusal is graded: when relevant material was found but it doesn't contain the specific answer, Honeycomb appends one sentence describing what the retrieved records do cover. You learn immediately whether the fact is missing from memory entirely, or just adjacent to what you asked.

curl -s "$HONEYCOMB_URL/api/v1/ask" \
  -H "Authorization: Bearer hck_live_9f3ab2..." \
  -H "Content-Type: application/json" \
  -d '{ "query": "Which audit firm is running our SOC 2 audit?" }'
{
  "answer": "I don't have that information. The retrieved context covers: SOC 2 readiness planning, the Q3 compliance timeline, and evidence-collection task assignments.",
  "answered": false,
  "confidence": 0,
  "citedIndices": [],
  "results": [
    {
      "id": "res_02k1p7",
      "knowledgeEntryId": "ke_44rt2b",
      "score": 0.71,
      "content": "Compliance sync: SOC 2 readiness kickoff set for July 20, evidence collection owners assigned...",
      "title": "Compliance weekly sync",
      "namespace": "ops",
      "contentType": "meeting_notes",
      "sourceAgent": "notetaker",
      "tags": ["compliance"],
      "validFrom": "2026-07-01T00:00:00.000Z",
      "sourceChannel": "#compliance"
    }
  ],
  "family": "single_hop",
  "coragExpanded": false,
  "mode": "hybrid",
  "searchTimeMs": 640
}

Follow-up moves from here: rephrase with the entity's exact name, widen or narrow the scope, or check Ingesting Data to confirm the source that would hold the fact is connected.

Scoping your question

By default a question runs over everything the caller is permitted to see — the whole organizational memory for an org-level key, or one person's view when x-acting-user is set. Two scopes narrow that to a single container:

  • scope.spaceId — answer only from one Space. For smaller Spaces, Honeycomb reads every record in the Space rather than relying on relevance ranking alone, so summaries and small details are covered end to end.
  • scope.threadId — answer only from one conversation. Ideal for "what was this thread about?" or "what did we decide here?".

Here's a conversation-scoped summary, asked on behalf of a specific user:

curl -s "$HONEYCOMB_URL/api/v1/ask" \
  -H "Authorization: Bearer hck_live_9f3ab2..." \
  -H "Content-Type: application/json" \
  -H "x-acting-user: [email protected]" \
  -d '{
    "query": "Summarize this conversation — key decisions and open action items.",
    "scope": { "threadId": "thr_8c2d41" }
  }'
{
  "answer": "The thread covers the Q3 launch plan for the analytics dashboard.\n\n- **Decision:** launch date moved to September 14 to allow a two-week beta [1].\n- **Decision:** pricing ships as a flat add-on, not usage-based [3].\n- **Action:** Priya to draft the beta invite list by Friday [2].\n- **Open:** security review slot still unconfirmed [4].",
  "answered": true,
  "confidence": 0.95,
  "citedIndices": [1, 3, 2, 4],
  "results": [
    { "id": "res_03m2q1", "knowledgeEntryId": "ke_10aa9d", "score": 0.84, "content": "Team agreed: push launch to Sept 14, gives us a full two-week beta window...", "title": "Launch planning", "namespace": "product", "contentType": "message", "sourceAgent": "slack-sync", "tags": ["q3-launch"], "validFrom": "2026-06-28T00:00:00.000Z", "sourceChannel": "#launch-q3" },
    { "id": "res_03m2q2", "knowledgeEntryId": "ke_10ab7e", "score": 0.79, "content": "Priya volunteered to draft the beta invite list by end of week.", "title": "Launch planning", "namespace": "product", "contentType": "message", "sourceAgent": "slack-sync", "tags": ["q3-launch"], "validFrom": "2026-06-28T00:00:00.000Z", "sourceChannel": "#launch-q3" },
    { "id": "res_03m2q3", "knowledgeEntryId": "ke_10ac5f", "score": 0.77, "content": "Pricing call: flat add-on, revisit usage-based after GA.", "title": "Launch planning", "namespace": "product", "contentType": "message", "sourceAgent": "slack-sync", "tags": ["q3-launch"], "validFrom": "2026-06-29T00:00:00.000Z", "sourceChannel": "#launch-q3" },
    { "id": "res_03m2q4", "knowledgeEntryId": "ke_10ad3a", "score": 0.72, "content": "Still waiting on a security review slot — flagged as launch risk.", "title": "Launch planning", "namespace": "product", "contentType": "message", "sourceAgent": "slack-sync", "tags": ["q3-launch"], "validFrom": "2026-06-30T00:00:00.000Z", "sourceChannel": "#launch-q3" }
  ],
  "family": "holistic",
  "coragExpanded": false,
  "mode": "hybrid",
  "searchTimeMs": 508
}

Space and conversation scoping stack with the caller's permissions — scoping to a Space never grants access the caller doesn't already have.

Question types that work well

Honeycomb detects the shape of your question and adapts how it answers. These patterns all perform well:

TypeExampleWhat you get back
Factual lookup"What's Acme Robotics' ARR?"One crisp value with a citation.
Small operational detail"What's the staging sandbox called?"The exact detail, even from a passing mention.
Timeline"How did the Northwind deal unfold?"Date-ordered bullets, one per event, each cited.
Profile / dossier"Give me a rundown on Priya Sharma."A concise attribute profile of the person or company.
Who knows about X"Who's been closest to the SSO migration?"The people most connected to the topic, with evidence.
Point in time"Who owned the Acme account as of 2026-03-01?"The value that was true then, even if it changed since.
Holistic summary"What was this conversation about?" (with scope.threadId)Gist plus decisions and action items across the whole thread.
Counting"How many open enterprise deals do we have?"A count over stored records, with the items behind it.
Conflict check"Do we have conflicting figures for Q2 pipeline?"Every distinct value on record, each cited — no silent tie-breaking.

Multi-part questions ("Compare X and Y and tell me which team owns each") work too — the engine runs follow-up retrieval when its first pass leaves gaps (coragExpanded: true in the response).

Choosing an effort level

effortSpeedBehaviorUse when
lowFastest — typically a few secondsSingle fast pass; skips follow-up retrieval and extra verificationAutocomplete-style lookups, latency-sensitive UI
medium (default)BalancedPer-question tuning; follow-up retrieval for multi-part questionsAlmost everything
highSlowestMaximum verification passes and the most careful readingHigh-stakes single facts where a wrong value is costly

Tips for better answers

  1. Name things precisely. "What's the Northwind renewal value?" beats "what's that deal worth?" — named entities anchor retrieval.
  2. One question per call. Two unrelated questions in one query split the evidence budget. Related multi-part questions are fine.
  3. Scope conversational questions. "What did we decide?" is ambiguous org-wide; with scope.threadId it's precise.
  4. Put dates in the question for historical facts. "Who owned the Acme account as of 2026-03-01?" triggers point-in-time handling automatically.
  5. Use filters to cut noise. scope.namespace, scope.source, and scope.dateRange keep a busy memory from drowning the signal.
  6. Read the graded refusal. The coverage sentence usually tells you exactly how to rephrase — or that the data was never ingested.
  7. Trust answered and confidence in automation. Gate downstream actions on answered === true, and treat low confidence as "verify the citations."

Asking from the console

The Ask page is the console's home screen — the same engine, zero setup:

  1. Open the console and type your question into the ask box (suggestion chips offer questions your memory can actually answer).
  2. Pick an effort level with the effort dial if you want faster or more careful answers.
  3. Read the answer with its citations; each [n] links to a source card showing the underlying record, where it came from, and when.
  4. Use the Timeline view for "how did this unfold?" questions rendered as a visual, date-ordered timeline.

See The Console for the full tour.

Errors

StatusBodyMeaning
400{ "error": "Validation error", "details": [...] }The request body failed validation — details name the field.
401{ "error": "..." }Missing or invalid API key.
503{ "error": "Answer engine not configured (no LLM provider)" }The answer engine is unavailable; retry, and contact support if it persists.
500{ "error": "Internal Server Error" }Unexpected failure — safe to retry.

Next steps