Integrations
Connect the Jamdesk Docs Search API to Intercom, Zendesk, Slack, and custom chatbots. Step-by-step guides for each integration.
This guide shows how to connect the Docs Search API to the most common tools: Intercom, Zendesk, Slack, and custom chatbots.
Intercom (Fin AI Agent)
Intercom's Fin AI Agent supports Data Connectors: external search sources that Fin queries alongside your Intercom articles. Connect the Docs Search 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 jd_live_ key (40 chars total).
In Intercom, go to AI Agent → Data Sources → Add Source → API.
Enter the following details:
| Field | Value |
|---|---|
| Endpoint URL | https://your-project.jamdesk.app/_api/search |
| Method | POST |
| Auth header | Authorization: Bearer jd_live_c83003a54ae0a83123454c3f7ec82f0a |
| Query field | query |
| Result path | results[*].content |
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, so 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 with 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 Docs Search API. Use the Docs Search API (with a jd_live_ key) when you need authenticated access, per-key rate limiting, or revocation control.
Custom Chatbots
Add documentation search to any chatbot or web app with a standard fetch call. CORS is enabled, so browser-based clients can call the API directly without a backend proxy.
async function searchDocs(query) {
const response = await fetch(
"https://your-project.jamdesk.app/_api/search",
{
method: "POST",
headers: {
"Authorization": "Bearer jd_live_c83003a54ae0a83123454c3f7ec82f0a",
"Content-Type": "application/json",
},
body: JSON.stringify({ query, limit: 5 }),
}
);
if (!response.ok) {
const { error } = await response.json();
throw new Error(error);
}
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.title}`);
console.log(result.content);
console.log(result.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.title}](${r.url})\n${r.content}`)
.join("\n\n---\n\n");
// 2. Pass context to Claude
const message = await client.messages.create({
model: "claude-sonnet-4-5-20241022",
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/_api/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.url}|${result.title}>*\n${result.content}`,
},
},
{ 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.
Subpath Hosting (Cloudflare Worker)
If you're using subpath hosting to serve your docs at a path on your domain (/docs by default, or a custom subpath like /help), the /_api route needs to be proxied through your Cloudflare Worker too, alongside your docs path.
Add /_api to the PROXY_PATHS array in your worker, using whichever path prefix you configured in the dashboard:
const PROXY_PATHS = [
"/docs", // or your custom subpath, e.g. "/help"
"/_jd",
"/_api", // Add this line
];
This ensures search requests to yoursite.com/_api/search (or yoursite.com/help/_api/search, if you're on a custom subpath) are forwarded to your Jamdesk docs site.
The /_api route requires authentication via your jd_live_ API key regardless of how the request is routed. Proxying through Cloudflare does not bypass authentication.
