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.
Honeycomb gets more useful the more of your organization's activity flows into it. Connectors are how that happens: point your tools' webhooks at your Honeycomb deployment, and every commit, conversation, deal, and ticket becomes searchable, permission-aware memory — automatically normalized, deduplicated, and scoped to the right people.
At a glance
- GitHub and Slack have dedicated signed webhook endpoints — no API key in the URL; each request is verified with an HMAC signature before anything is stored.
- CRMs, ticket trackers, and email-style payloads push to
POST /api/v1/webhook/:sourcewith yourhck_...API key. - Your own systems can push anything via
POST /api/v1/ingest— see Ingesting Data. - Every record carries a stable external reference, so webhook redeliveries and record updates never create duplicates — updates supersede older versions in place.
- Access is inherited from the source: public channels and repos become org-readable; private channels are scoped to their members; emails are scoped to their recipients. When in doubt, Honeycomb fails closed to private.
- Prefer one click? An org admin can connect a whole company's CRM, Linear, or Slack from the Lua app with no webhook setup — and Lua CRM feeds memory natively with zero setup at all — see Company Connections.
- Monitor everything with
GET /api/v1/sources/healthor the Sources page in the console.
How live data flows in
| Entry point | Auth | Best for |
|---|---|---|
POST /api/v1/webhook/github | HMAC signature (webhook secret) | GitHub repos and orgs |
POST /api/v1/webhook/slack | HMAC signature (signing secret) | Slack workspaces |
POST /api/v1/webhook/:source | Authorization: Bearer hck_... | CRM records, tickets, email, anything else |
POST /api/v1/ingest | Authorization: Bearer hck_... | Direct pushes from your own pipelines |
Once normalized, everything downstream is identical regardless of source — the same search, Ask, and Spaces behavior applies to a Slack thread and a CRM deal alike.
GitHub
Set it up
- Get your deployment's GitHub webhook secret. It's configured on your Honeycomb deployment when the connector is enabled — generate a strong random string and set it during onboarding (your Lua contact can confirm it's in place).
- In GitHub, go to your repository or organization Settings → Webhooks → Add webhook.
- Set Payload URL to
https://YOUR_HONEYCOMB_HOST/api/v1/webhook/github. - Set Content type to
application/json. - Paste the same secret into the Secret field.
- Choose Let me select individual events and pick: Pushes, Pull requests, Issues, Issue comments, Pull request reviews.
- Save. GitHub sends a ping event; Honeycomb acknowledges it and you'll see a green checkmark in GitHub's recent deliveries.
Every delivery is verified against the X-Hub-Signature-256 header using a constant-time comparison. Requests with a missing or invalid signature are rejected with 401.
Note: If the endpoint returns
503withWebhook verification not configured, the webhook secret hasn't been set on your deployment yet — finish step 1 first.
What lands in memory
| GitHub event | Stored as | What Honeycomb extracts |
|---|---|---|
| Push | Commit records | Commit authors as people, the repo, who works on what |
| Pull request | Pull request record | Title, body, assignees and requested reviewers as people |
| Issue | Ticket record | Title, body, assignee, labels as tags |
| Issue comment | Message record | Comment text in context of its issue |
| PR review | Code review record | Review body and verdict |
Events outside these five are still accepted (and acknowledged) but stored as low-fidelity generic records — which is why we recommend selecting individual events rather than "send me everything."
Visibility and access
- Public and internal repos are treated as org-visible: anyone in your organization can retrieve their content.
- Private repos fail closed: content is ingested but scoped privately, since the webhook payload doesn't carry a collaborator roster.
Slack
Set it up
- Create a Slack app for your workspace (or reuse an existing one) at api.slack.com.
- From the app's Basic Information page, copy the Signing Secret and configure it on your Honeycomb deployment (same onboarding path as the GitHub secret).
- Under Event Subscriptions, enable events and set the Request URL to
https://YOUR_HONEYCOMB_HOST/api/v1/webhook/slack. Honeycomb answers Slack's URL-verification challenge automatically, so the URL verifies immediately. - Subscribe to bot events:
message.channels,message.groups,message.im,message.mpim(pick the subset you want captured). - Install a bot token with read scopes on your deployment as well — this is what lets Honeycomb resolve user IDs to names, stitch threads together, and read private-channel membership.
- Install the app to your workspace and invite the bot to the channels you want remembered.
Every event is verified with Slack's v0 HMAC scheme (X-Slack-Signature + X-Slack-Request-Timestamp), with a five-minute replay window — stale or unsigned requests get 401.
Threads become living memories
Slack conversations evolve, and Honeycomb tracks that instead of storing a pile of fragments.
Each reply re-ingests the whole thread as one transcript and supersedes the previous version — so search always finds the current state of the conversation, never a stale fragment. Deep entity and fact extraction waits for a quiet period (about 30 minutes of no new replies by default) so a busy thread is enriched once, not on every message.
People and privacy
- User mapping is automatic. Slack user IDs resolve to real names and profile emails, and feed Honeycomb's identity graph — so "what did Priya say about the migration?" works even though Slack only sent
U04AB12CD. The same graph links a person's Slack identity to their email and GitHub identity across sources. - Public channels are org-visible: anyone in your organization can retrieve their content.
- Private channels are scoped to their member roster — Honeycomb reads the membership and grants retrieval to exactly those people. In very large private channels, grants cover the first 200 members.
- When privacy can't be determined (for example, the bot token is missing), Honeycomb fails closed and keeps the content private.
Warning: Without a bot token, threaded messages degrade to standalone messages and user/channel IDs are stored raw (
U04AB12CDinstead of names). The connector still works, but recall quality drops noticeably — install the bot token.
Generic webhooks: CRM, tickets, email
POST /api/v1/webhook/:source is the authenticated catch-all for everything that isn't GitHub or Slack. Unlike the two signed endpoints, it uses your normal API key:
Authorization: Bearer hck_your_api_keyThree source names get first-class structured parsing. Anything else is accepted as free-form.
| Path | Payload shape | Stored as |
|---|---|---|
/api/v1/webhook/email | from, to, cc, subject, body, messageId, threadId, date | Email — readable only by the people on it |
/api/v1/webhook/crm | recordType, id, name, fields, platform, updatedAt | CRM record with deal, owner, and account entities |
/api/v1/webhook/ticket | key, summary, description, status, assignee, reporter, priority, labels, project, platform, updatedAt | Ticket with assignee and project entities |
| any other name | Free-form JSON — text pulled from text, body, content, or message | Generic record tagged with your source name |
Example: push a CRM deal
Works for any CRM — set platform to identify yours:
curl -X POST "https://YOUR_HONEYCOMB_HOST/api/v1/webhook/crm" \
-H "Authorization: Bearer hck_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"recordType": "deal",
"id": "deal-88412",
"name": "Northwind Traders - Enterprise Renewal",
"platform": "hubspot",
"updatedAt": "2026-07-07T09:14:00Z",
"fields": {
"stage": "negotiation",
"amount": 84000,
"owner": "Maya Chen",
"account": "Northwind Traders",
"close_date": "2026-08-15"
}
}'Honeycomb extracts the deal, its owner, and the account as linked entities, and records each field as a fact on the deal — so stage and amount are queryable, not just full-text-searchable. When the deal changes, push it again with the same id: the update supersedes the old version.
Response (201 Created):
{
"id": "km_9f3c2e71",
"chunksCreated": 1,
"entitiesExtracted": 3,
"factsRecorded": 4,
"extractionTier": 1
}Example: push a ticket
curl -X POST "https://YOUR_HONEYCOMB_HOST/api/v1/webhook/ticket" \
-H "Authorization: Bearer hck_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"key": "ENG-1432",
"summary": "Checkout latency spikes above 2s at peak",
"description": "p95 latency regressed after the cache change...",
"status": "In Progress",
"priority": "High",
"labels": ["performance", "checkout"],
"assignee": { "name": "Diego Ramos" },
"reporter": { "name": "Sam Okafor" },
"project": { "name": "Payments", "key": "PAY" },
"platform": "linear",
"updatedAt": "2026-07-07T08:02:11Z"
}'Anything else: the firehose
Unknown source names are accepted too — Honeycomb pulls the best available text and tags the record with your source name:
curl -X POST "https://YOUR_HONEYCOMB_HOST/api/v1/webhook/statuspage" \
-H "Authorization: Bearer hck_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "text": "Incident resolved: API error rate back to baseline as of 09:40 UTC." }'This is a great starting point for a new integration — you can graduate to fully structured pushes via Ingesting Data later without changing anything downstream.
Push from your own systems
If you control the sender, you don't need a webhook shape at all — call POST /api/v1/ingest with content, metadata, and optional pre-extracted entities. It also auto-detects the structured payloads above, and an X-Source header (for example X-Source: crm) forces a specific interpretation when a payload is ambiguous. Full details, including audience scoping and extraction tiers, live in Ingesting Data and the API Reference.
Monitoring source health
The health endpoint
curl "https://YOUR_HONEYCOMB_HOST/api/v1/sources/health" \
-H "Authorization: Bearer hck_your_api_key"{
"sources": [
{
"source": "slack",
"count": 1423,
"lastSeen": "2026-07-07T09:12:44.000Z",
"enrichment": { "complete": 1390, "pending": 21, "failed": 12 },
"backlog": 33
},
{
"source": "github",
"count": 611,
"lastSeen": "2026-07-07T08:55:10.000Z",
"enrichment": { "complete": 611 },
"backlog": 0
}
],
"totalBacklog": 33,
"generatedAt": "2026-07-07T09:15:00.000Z"
}| Field | Meaning |
|---|---|
sources[].count | Total records ever ingested from this source |
sources[].lastSeen | Timestamp of the most recent record — your freshness signal |
sources[].enrichment | Records by processing status (complete, pending, failed) |
sources[].backlog | Records still pending or failed |
totalBacklog | Backlog summed across all sources |
Two things to watch: a stale lastSeen on a source that should be chatty means deliveries stopped (check the webhook config on the sender's side), and a growing backlog means ingestion is outpacing enrichment.
Warning: The GitHub and Slack webhook endpoints deliberately return
200even when processing fails internally — this prevents the provider from hammering your deployment with redeliveries. Don't monitor connector health via webhook HTTP status codes; monitorlastSeenandbackloghere instead.
The Sources page in the console
The console gives you the same picture visually. Open Sources in the sidebar:
- Overview tab — enrichment throughput plus per-source cards showing volume, last-seen, and backlog at a glance.
- Documents tab — browse individual ingested documents with their full provenance: which source, which channel, when, and what was extracted.
Troubleshooting
| Symptom | Likely cause |
|---|---|
503 Webhook verification not configured | The GitHub or Slack secret isn't set on your deployment yet |
401 Missing signature / 401 Invalid signature | Secret mismatch between the sender and your deployment — re-paste it on both sides |
401 Request too old (Slack) | Delivery arrived more than 5 minutes after signing — usually clock skew or a slow proxy in front of your deployment |
Slack messages stored with raw IDs like U04AB12CD | Bot token missing — names, threads, and private-channel scoping all need it |
| GitHub deliveries show green but nothing appears | Event type isn't one of the five structured kinds, or check backlog on the health endpoint |
| Duplicate-looking records | Usually not duplicates — check for differing external references; true redeliveries are deduplicated automatically |
Next up: control who can retrieve what with Spaces & Permissions, or start asking questions with Ask.
Ingesting Your Data
Send messages, documents, tickets, and files into Honeycomb with the ingest and upload APIs — including batching, deduplication, updates, and deletion.
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.