Docs Search API
Search your Jamdesk docs programmatically. Power chatbots, Slack bots, custom search, and AI agents with up-to-date answers.
The Docs Search API gives you programmatic access to your documentation content via semantic search. One endpoint (POST /_api/search) takes a natural language query and returns the most relevant passages from your docs, ranked by relevance.
Use Cases
Quick Start
Go to Project Settings → API Keys in the Jamdesk dashboard. Click Generate Key, give it a name, and copy the key. It starts with jd_live_ followed by 32 hex characters (40 chars total) and is only shown once.
Send a POST request to /_api/search on your docs subdomain:
curl -X POST https://your-project.jamdesk.app/_api/search \
-H "Authorization: Bearer jd_live_c83003a54ae0a83123454c3f7ec82f0a" \
-H "Content-Type: application/json" \
-d '{"query": "How do I set up a custom domain?", "limit": 5, "language": "en"}'The response returns an array of matching passages with relevance scores and page metadata:
{
"query": "How do I set up a custom domain?",
"language": "en",
"results": [
{
"title": "Custom Domains",
"section": "Step 4: Deploy",
"slug": "deploy/custom-domains",
"content": "To add a custom domain, go to Project Settings and enter your domain. You'll need to add a CNAME record pointing to your Jamdesk subdomain.",
"url": "https://your-project.jamdesk.app/deploy/custom-domains",
"score": 0.94
}
],
"total": 1,
"durationMs": 85
}Authentication
All requests require a Bearer token in the Authorization header.
Authorization: Bearer jd_live_c83003a54ae0a83123454c3f7ec82f0a
Generating API Keys
In the Jamdesk dashboard, navigate to your project and click Settings.
Select the API Keys tab.
Click Generate Key, enter a descriptive name (e.g. "Intercom chatbot"), and click Create.
Copy the key immediately. It starts with jd_live_ followed by 32 hex characters and is shown only once. Store it in your secrets manager or environment variables.
Key Management
API keys are scoped to a single project. A key for acme.jamdesk.app cannot query a different project's documentation.
| Rule | Detail |
|---|---|
| Format | jd_live_<32 hex chars> (40 chars total, never expires) |
| Scope | One key per project (cannot access other projects) |
| Rotation | Revoke and regenerate anytime from Project Settings |
| Storage | Store in environment variables or a secrets manager; never commit to source control |
Revoking Keys
To revoke a key, go to Project Settings → API Keys, find the key by name, and click Revoke. Revoked keys stop working immediately. Generate a new key to replace it.
Rate Limits
Requests are rate-limited per API key.
| Plan | Limit |
|---|---|
| Pro | 60 requests / minute |
| Enterprise | Custom; contact support |
When you exceed the limit, the API returns 429 Too Many Requests with a Retry-After: 60 header and {"error": "Rate limit exceeded"} in the body.
If you need higher rate limits for a production integration, contact us to discuss Enterprise options.
Query Limits
Each request accepts a limit parameter controlling how many results to return. The maximum is 20, the default is 5, and the minimum is 1. There is no pagination; all matching results come back in a single response. If you need more context, try a more specific query rather than increasing the limit.
A query with no matches returns HTTP 200 with an empty results array:
{"query": "quantum entanglement", "results": [], "total": 0, "durationMs": 48}
Filtering by language
If your docs site supports multiple languages, the API filters results to a single language per request. Pass language in the request body with a BCP-47 code (e.g. en, es, fr, pt-BR, zh-Hans).
curl -X POST https://your-project.jamdesk.app/_api/search \
-H "Authorization: Bearer jd_live_c83003a54ae0a83123454c3f7ec82f0a" \
-H "Content-Type: application/json" \
-d '{"query": "¿Cómo configuro un dominio personalizado?", "language": "es"}'
| Rule | Detail |
|---|---|
| Default | en (English). Omit the field, or pass null, to use the default. |
| Format | BCP-47 (^[a-zA-Z]{2,3}([-_][a-zA-Z]{2,4})?$). Examples: en, es, fr, pt-BR, zh-Hans. |
| Validation | Malformed values return 400 with {"error": "Invalid language code"}. |
| 3-segment tags | Not currently supported. Codes like zh-Hant-HK and sr-Latn-RS return 400. Contact support if you need them. |
| Multi-language projects | The filter is strict — only chunks tagged with the requested language are returned. A request for de against a project that only has English and French returns an empty result set, not a 400. |
| Single-language projects | The filter is ignored; you always get the full result set. Sending language is harmless — not an error. |
| Echoed in response | Every successful response includes a language field with the value the server resolved (request value, or en default). |
A project is multi-language when its docs.json has a navigation.languages array with two or more entries. To check whether your site is multi-language, open the Settings → Languages tab in the dashboard, or open docs.json directly.
The default en applies even on projects that don't have an English version. If your multi-language project is e.g. French and Spanish only, calling the endpoint without a language field will filter for en and return an empty result set. Always pass an explicit language from non-English-only sites.
Error Handling
All error responses include a machine-readable error field you can branch on programmatically.
| Status | error value | Meaning | Action |
|---|---|---|---|
| 400 | Missing or empty "query" field | Request body is missing or has no query | Add a non-empty query string |
| 400 | Invalid language code | The language field is not a string or doesn't match the BCP-47 pattern (null is fine; empty/whitespace strings and 3-segment tags are not) | Use a valid 1- or 2-segment code like en, es, fr, or pt-BR |
| 401 | invalid_key_format | Authorization header is missing or the key doesn't match jd_live_<32 hex> | Check the header format; it must be Bearer jd_live_... |
| 401 | invalid_key | Key is not recognised or has been revoked | Generate a new key in the dashboard |
| 403 | wrong_project | Key is valid but was generated for a different project | Use a key that matches the project slug in the URL |
| 429 | Rate limit exceeded | Exceeded 60 requests per minute | Wait the number of seconds in the Retry-After header |
| 502 | Search temporarily unavailable | Vector search backend is down | Retry after a short backoff |
| 503 | lookup_failed or redis_unavailable | Key verification backend is unreachable | Retry after a short backoff |
401 and 403 are permanent failures. Retrying with the same key won't help. 429, 502, and 503 are transient, so retry with exponential backoff.
CORS
CORS is enabled on all endpoints. Browser-based clients (single-page apps, browser extensions, static sites) can call /_api/search directly without a backend proxy. All origins are allowed.
SDKs
There are no official language SDKs at this time. Use the REST API directly via fetch, requests, curl, or any HTTP client. The Postman collection below provides ready-to-fork examples.
Versioning
The API is currently at v1.0.0. Breaking changes (field renames, removed endpoints, changed auth) will be announced via the Jamdesk blog and a deprecation notice in the X-Deprecation response header at least 90 days before removal.
OpenAPI Specification
The full OpenAPI 3.1 spec is available as YAML. Import it into your codegen tool, API client, or contract-testing pipeline.
Postman Collection
We publish an official Postman workspace with the full OpenAPI spec and a ready-to-fork collection so you can test requests in the Postman UI without writing any code.
After forking the collection, you must update two collection variables before any request will work:
baseUrl: set to your own Jamdesk docs site. For most customers this ishttps://your-project.jamdesk.app(replaceyour-projectwith your project slug). Custom-domain customers use their own host. Customers serving docs under a sub-path include the full path (e.g.https://example.com/docs).apiKey: replace the placeholder with a real key generated in Dashboard → Project Settings → API Keys.
