Sample Code and Troubleshooting Guidance for Knowledge Access API
This topic provides reusable client-side code samples and error handling guidance for developers integrating with the Knowledge Access API. It complements the Uploading Knowledge Base Documents Using Push API topic and is intended for technical audiences working with automation and backend systems.
Client Examples
The following example demonstrates how to use the Knowledge Access API to upload, edit, delete, and retrieve documents programmatically.
const fs = require("fs");
const FormData = require("form-data"); // ← use Node-compatible FormData
const token = "your_token_here"; // ← replace with your actual token
const instanceUrl = "https://your-instance.salesforce.com"; // ← replace with real instance URL
const documentId = "your_document_id_here"; // ← replace with actual document ID if needed
const name = "Pump Manual"; // ← replace with actual document name
const sourceName = "SharePoint"; // ← replace with actual source name
const relevantProductIds = "001xx000003DGSWAA4,001xx000003DGSWAAB"; // ← replace with actual product IDs
const filePath = "docs/pump-manual.pdf"; // ← replace with actual file path
const sourceUrl = "https://example.com/pump-manual.pdf"; // ← replace with actual source URL if needed
const api = "https://aika-max-prod.servicemax.io/documents";

async function addDocument() {
const fetch = (await import("node-fetch")).default;

const form = new FormData();
form.append("name", name);
form.append("source_name", sourceName);
form.append("relevant_product_ids", relevantProductIds);
form.append(
"file",
fs.createReadStream(filePath),
filePath.substring(filePath.lastIndexOf("/") + 1)
);
form.append("url", sourceUrl);

const res = await fetch(api, {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"X-Salesforce-Instance-Url": instanceUrl,
...form.getHeaders(),
},
body: form,
});

const status = res.status;
const text = await res.text();
console.log({ status, response: text });
}

async function deleteDocument() {
const fetch = (await import("node-fetch")).default;

const res = await fetch(`${api}/${documentId}`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${token}`,
"X-Salesforce-Instance-Url": instanceUrl,
},
});

const status = res.status;
const text = await res.text();
console.log({ status, response: text });
}

async function editDocument() {
const fetch = (await import("node-fetch")).default;

const form = new FormData();
form.append("name", name); // Optional
form.append("source_name", sourceName); // Optional
form.append("relevant_product_ids", relevantProductIds); // Optional
form.append(
"file",
fs.createReadStream(filePath),
filePath.substring(filePath.lastIndexOf("/") + 1)
); // Optional
form.append("url", sourceUrl); // Optional

const res = await fetch(`${api}/${documentId}`, {
method: "PUT",
headers: {
Authorization: `Bearer ${token}`,
"X-Salesforce-Instance-Url": instanceUrl,
...form.getHeaders(),
},
body: form,
});

const status = res.status;
const text = await res.text();
console.log({ status, response: text });
}

async function getDocuments() {
const fetch = (await import("node-fetch")).default;
const params = new URLSearchParams({
offset: "0", // Optional parameter to specify the starting point of results, by default is 0
page_size: "100", // Optional parameter to limit the number of results, by default is 100
include_total: "true", // Optional parameter to include total count
document_ids: "7b59b08d-d16c-401f-8e71-074a5d58fa4a", // Optional filter by document ID
});
const apiWithParams = `${api}?${params.toString()}`;

const res = await fetch(apiWithParams, {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
"X-Salesforce-Instance-Url": instanceUrl,
},
});

const status = res.status;
const text = await res.text();
console.log({ status, response: text });
}

async function main() {
console.log("Starting API tests...\n");

try {
// Uncomment the functions you want to test
// await addDocument();
// console.log("\n" + "=".repeat(50) + "\n");

// await deleteDocument();
// console.log("\n" + "=".repeat(50) + "\n");

// await editDocument();
// console.log("\n" + "=".repeat(50) + "\n");

await getDocuments();
} catch (err) {
console.error("Error in main:", err);
}
}

// Run the main function
main();
Rate Limiting & Usage Guardrails
To ensure fair usage and protect system stability, the Knowledge Access API enforces rate limits at the org level.
Configuration-Based Limits
You can configure rate limits per org using a Max Setting. The default limits are:
{
"upload_per_minute": 5,
"edit_per_minute": 5,
"delete_per_minute": 10,
"get_info_per_minute": 30
}
Endpoint Limits
Field
Description
POST /documents
Max 5 uploads per minute
PUT /documents/{id}
Max 5 updates per minute
DELETE /documents/{id}
Max 10 deletes per minute
GET /documents
Max 30 gets per minute
* 
When a setting is updated in Max, the cache must be refreshed.
Sample Response for Rate Limit Exceeded
{
"error": {
"code": 429,
"type": "rate_limit_exceeded",
"message": "Too many requests. Please try again later.",
"retry_after": 60
}
}
Error Codes and Troubleshooting
This section lists common error codes that may occur during API interactions. Each entry includes the error type, message, and a sample response to help identify and resolve issues.
Error Code
Type
Message
401
authentication_error
Authentication token is missing or invalid.
403
authorization_error
You do not have permission to access this resource.
429
rate_limit_exceeded
Too many requests. Please try again later.
Sample Error Responses
401 Unauthorized
{
"error": {
"code": 401,
"type": "authentication_error",
"message": "Authentication token is missing or invalid."
}
}
403 Unauthorized
{
"error": {
"code": 403,
"type": "authorization_error",
"message": "You do not have permission to access this resource."
}
}
429 Rate Limit Exceeded
{
"error": {
"code": 429,
"type": "rate_limit_exceeded",
"message": "Too many requests. Please try again later.",
"retry_after": 60
}
}
Was this helpful?