Integrations
Connect the Jamdesk Knowledge API to Intercom, Zendesk, Slack, and custom chatbots. Step-by-step guides for each integration.
The Knowledge API is designed to plug into the tools your team and customers already use. This guide covers the most common integrations.
Intercom (Fin AI Agent)
Intercom's Fin AI Agent supports Data Connectors — external search sources that Fin queries alongside your Intercom articles. Connect the Knowledge API so Fin can answer questions directly from your Jamdesk docs.
In the Jamdesk dashboard, go to Project Settings → API Keys and click Generate Key. Name it "Intercom Fin" and copy the jdk_ key.
In Intercom, go to AI Agent → Data Sources → Add Source → API.
Enter the following details:
| Field | Value |
|---|---|
| Endpoint URL | https://your-project.jamdesk.app/_knowledge/search |
| Method | POST |
| Auth header | Authorization: Bearer jdk_your_key_here |
| Query field | query |
| Result path | results[*].text |
Use Intercom's built-in test tool to send a sample query. Verify Fin returns relevant passages from your docs.
Turn on the data connector in your Fin configuration. Fin will now cite your documentation when answering customer questions.
Fin respects the score field — higher-scoring results appear first in its answers. Passages with a score below 0.7 are typically not used.
Zendesk (MCP Server)
Zendesk's AI features support MCP servers as knowledge sources. Use Jamdesk's built-in MCP server to connect your docs to Zendesk's AI agents — no custom code required.
Your MCP server is available at https://your-project.jamdesk.app/_jd/mcp. No API key is required for the MCP server — it uses your project's public docs.
In Zendesk Admin Center, go to AI Agents → Knowledge Sources → Add MCP Server.
Paste your MCP server URL: https://your-project.jamdesk.app/_jd/mcp
Zendesk will list the available tools (searchDocs, getPage). Confirm both tools are detected, then save.
The MCP server exposes the same search index as the Knowledge API. Use the Knowledge API (with a jdk_ key) when you need authenticated access or want to control rate limits per integration.
Custom Chatbots
Add documentation search to any chatbot or web app with a standard fetch call.
async function searchDocs(query) {
const response = await fetch(
"https://your-project.jamdesk.app/_knowledge/search",
{
method: "POST",
headers: {
"Authorization": "Bearer jdk_your_key_here",
"Content-Type": "application/json",
},
body: JSON.stringify({ query, limit: 5 }),
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.message);
}
const data = await response.json();
return data.results;
}
// Example usage
const results = await searchDocs("How do I configure a custom domain?");
results.forEach((result) => {
console.log(`[${result.score.toFixed(2)}] ${result.page.title}`);
console.log(result.text);
console.log(result.page.url);
console.log("---");
});
Building an AI Agent Tool
Pass search results as context to a language model to generate grounded answers:
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
async function answerFromDocs(userQuestion) {
// 1. Search your docs
const results = await searchDocs(userQuestion);
const context = results
.map((r) => `[${r.page.title}](${r.page.url})\n${r.text}`)
.join("\n\n---\n\n");
// 2. Pass context to Claude
const message = await client.messages.create({
model: "claude-haiku-4-5",
max_tokens: 1024,
messages: [
{
role: "user",
content: `Answer the following question using only the provided documentation excerpts.
If the answer isn't in the docs, say so.
Documentation:
${context}
Question: ${userQuestion}`,
},
],
});
return message.content[0].text;
}
Slack Bots
Build a /docs Slack slash command that searches your documentation and posts results to any channel.
import { App } from "@slack/bolt";
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
});
app.command("/docs", async ({ command, ack, respond }) => {
await ack();
const query = command.text.trim();
if (!query) {
await respond("Usage: `/docs <your question>`");
return;
}
try {
const response = await fetch(
"https://your-project.jamdesk.app/_knowledge/search",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.JAMDESK_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ query, limit: 3 }),
}
);
const data = await response.json();
if (data.results.length === 0) {
await respond(`No results found for: _${query}_`);
return;
}
const blocks = [
{
type: "section",
text: {
type: "mrkdwn",
text: `*Results for:* _${query}_`,
},
},
{ type: "divider" },
...data.results.flatMap((result) => [
{
type: "section",
text: {
type: "mrkdwn",
text: `*<${result.page.url}|${result.page.title}>*\n${result.text}`,
},
},
{ type: "divider" },
]),
];
await respond({ blocks });
} catch (err) {
await respond(`Error searching docs: ${err.message}`);
}
});
(async () => {
await app.start(process.env.PORT || 3000);
console.log("Slack bot is running");
})();
Set JAMDESK_API_KEY in your Slack app's environment variables — never hardcode the key.
hostAtDocs (Cloudflare Worker)
If you're using hostAtDocs to serve your docs at a subpath (e.g. yoursite.com/docs), the /_knowledge route needs to be proxied through your Cloudflare Worker.
Add /_knowledge to the PROXY_PATHS array in your worker:
const PROXY_PATHS = [
"/docs",
"/_jd",
"/_knowledge", // Add this line
];
This ensures search requests to yoursite.com/_knowledge/search are forwarded to your Jamdesk docs site.
The /_knowledge route requires authentication via your jdk_ API key regardless of how the request is routed. Proxying through Cloudflare does not bypass authentication.
