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 call —
POST /api/v1/askwith{ "query": "..." }returns a complete answer as a single JSON body. - Every claim is cited — inline
[n]markers in the answer map to entries in theresultsarray, 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
effortfield 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:
/askreturns 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
| Header | Value | Notes |
|---|---|---|
Authorization | Bearer hck_... | Required. Your organization's API key. |
Content-Type | application/json | Required. |
x-acting-user | A user's email | Optional. 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.
| Field | Type | Default | What it does |
|---|---|---|---|
query | string, 1–10000 chars | required | Your question, in plain language. |
effort | low medium high | medium | Speed vs. thoroughness — see Choosing an effort level. |
limit | int, 1–200 | 10 | Maximum evidence items retrieved for the answer. |
asOf | ISO date string | now | Anchors the reader's sense of "today" — useful for questions about a past state. |
mode | hybrid semantic keyword graph temporal | hybrid | Retrieval flavor. The default is right for almost all questions. |
scope.spaceId | string | — | Answer only from one Space's records. |
scope.threadId | string | — | Answer only from one conversation. |
scope.namespace | string or string array | — | Restrict to a namespace, e.g. "sales". |
scope.source | string or string array | — | Restrict by source platform, e.g. "slack". |
scope.sourceChannel | string or string array | — | Restrict by channel, e.g. "#engineering". |
scope.contentType | string or string array | — | Restrict by record type, e.g. "meeting_notes". |
scope.agents | string or string array | — | Restrict by the agent that wrote the memory. |
scope.tags | string array | — | All listed tags must match. |
scope.dateRange | object with from / to ISO dates | — | Only 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
| Field | Type | Meaning |
|---|---|---|
answer | string | The answer in Markdown, with inline [n] citations — or the refusal text. |
answered | boolean | true when Honeycomb actually answered. false on refusal or when nothing relevant was found. |
confidence | number | 0 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. |
citedIndices | number array | The [n] markers actually used in the answer (1-based, deduplicated). |
results | array | The full evidence set, in reading order. Each item includes content, title, namespace, contentType, sourceChannel, tags, dates, and a relevance score. |
family | string | The engine's read on the question type (factual, timeline, profile, and so on). Useful for analytics; safe to ignore. |
coragExpanded | boolean | true when the engine ran extra follow-up retrieval to fill evidence gaps for a multi-part question. |
mode | string | The retrieval mode that ran. |
searchTimeMs | number | Time spent finding evidence. |
Warning: Programmatically, always branch on the
answeredboolean — never string-match the answer text. A graded refusal still contains useful prose, butansweredstaysfalse.
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:
| Type | Example | What 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
effort | Speed | Behavior | Use when |
|---|---|---|---|
low | Fastest — typically a few seconds | Single fast pass; skips follow-up retrieval and extra verification | Autocomplete-style lookups, latency-sensitive UI |
medium (default) | Balanced | Per-question tuning; follow-up retrieval for multi-part questions | Almost everything |
high | Slowest | Maximum verification passes and the most careful reading | High-stakes single facts where a wrong value is costly |
Tips for better answers
- Name things precisely. "What's the Northwind renewal value?" beats "what's that deal worth?" — named entities anchor retrieval.
- One question per call. Two unrelated questions in one query split the evidence budget. Related multi-part questions are fine.
- Scope conversational questions. "What did we decide?" is ambiguous org-wide; with
scope.threadIdit's precise. - Put dates in the question for historical facts. "Who owned the Acme account as of 2026-03-01?" triggers point-in-time handling automatically.
- Use filters to cut noise.
scope.namespace,scope.source, andscope.dateRangekeep a busy memory from drowning the signal. - Read the graded refusal. The coverage sentence usually tells you exactly how to rephrase — or that the data was never ingested.
- Trust
answeredandconfidencein automation. Gate downstream actions onanswered === 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:
- Open the console and type your question into the ask box (suggestion chips offer questions your memory can actually answer).
- Pick an effort level with the effort dial if you want faster or more careful answers.
- Read the answer with its citations; each
[n]links to a source card showing the underlying record, where it came from, and when. - 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
| Status | Body | Meaning |
|---|---|---|
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
- Want raw ranked passages instead of a composed answer? Use Search and Recall.
- Giving an AI agent access to memory? See Agents and MCP.
- Controlling who can ask about what? See Spaces and Permissions.
- Full endpoint catalog: API Reference.
Connectors & Webhooks
Wire GitHub, Slack, CRMs, ticket trackers, and your own systems into Honeycomb with signed webhooks and authenticated push endpoints — then watch source health live.
Search & Recall
Retrieve your organization's memory programmatically — ranked search, memory browsing, point-in-time queries, the people directory, and full exports.