import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
});
async function main() {
const response = await client.knowledgeBase.updateFaq({
context_id: '00000000-0000-0000-0000-000000000000',
question: 'What is Periskope?',
});
console.log(response);
}
main();curl -X PATCH 'https://api.periskope.app/v1/knowledge-base/faq/00000000-0000-0000-0000-000000000000' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"question": "What is Periskope?"
}'[
{
"context_id": "00000000-0000-0000-0000-000000000000",
"org_id": "00000000-0000-0000-0000-000000000000",
"question": "What is Periskope?",
"answer": "Periskope is a platform to manage WhatsApp at scale.",
"type": "faq",
"embedding": "[-0.0123,0.0456,0.0789,...]",
"attachments": [
{
"link": {
"url": "org-assets/00000000-0000-0000-0000-000000000000/ai_assets/00000000-0000-0000-0000-000000000000/pricing.pdf",
"type": "application/pdf",
"name": "pricing.pdf"
}
}
],
"avg_rating": null,
"document_id": "00000000-0000-0000-0000-000000000000",
"is_active": true,
"metadata": {
"fileName": "product-faq.pdf",
"chunkIndex": 1,
"tokenCount": 180,
"source": "qa"
},
"tags": null,
"created_at": "2026-01-15T09:30:00.000Z",
"updated_at": "2026-01-15T09:30:00.000Z"
}
]{
"code": "UNAUTHORIZED_ERROR",
"message": "Invalid bearer auth token",
"status": 401
}{
"code": "NOT_FOUND_ERROR",
"message": "No FAQ matches context_id",
"status": 404
}{
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"status": 422,
"fields": {
"body.chat_id": {
"message": "chat_id is required"
}
}
}{
"code": "RATE_LIMIT_ERROR",
"message": "You can only make 100 requests per second",
"status": 429
}{
"code": "UNKNOWN_ERROR",
"message": "Internal server error",
"status": 500
}Update FAQ
Updates the FAQ addressed by the path context_id. Send question and answer together to replace the text and regenerate its embedding (attachments are then cleared unless resent); attachments and is_active can also be updated alone — omitted fields stay unchanged.
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
});
async function main() {
const response = await client.knowledgeBase.updateFaq({
context_id: '00000000-0000-0000-0000-000000000000',
question: 'What is Periskope?',
});
console.log(response);
}
main();curl -X PATCH 'https://api.periskope.app/v1/knowledge-base/faq/00000000-0000-0000-0000-000000000000' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"question": "What is Periskope?"
}'[
{
"context_id": "00000000-0000-0000-0000-000000000000",
"org_id": "00000000-0000-0000-0000-000000000000",
"question": "What is Periskope?",
"answer": "Periskope is a platform to manage WhatsApp at scale.",
"type": "faq",
"embedding": "[-0.0123,0.0456,0.0789,...]",
"attachments": [
{
"link": {
"url": "org-assets/00000000-0000-0000-0000-000000000000/ai_assets/00000000-0000-0000-0000-000000000000/pricing.pdf",
"type": "application/pdf",
"name": "pricing.pdf"
}
}
],
"avg_rating": null,
"document_id": "00000000-0000-0000-0000-000000000000",
"is_active": true,
"metadata": {
"fileName": "product-faq.pdf",
"chunkIndex": 1,
"tokenCount": 180,
"source": "qa"
},
"tags": null,
"created_at": "2026-01-15T09:30:00.000Z",
"updated_at": "2026-01-15T09:30:00.000Z"
}
]{
"code": "UNAUTHORIZED_ERROR",
"message": "Invalid bearer auth token",
"status": 401
}{
"code": "NOT_FOUND_ERROR",
"message": "No FAQ matches context_id",
"status": 404
}{
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"status": 422,
"fields": {
"body.chat_id": {
"message": "chat_id is required"
}
}
}{
"code": "RATE_LIMIT_ERROR",
"message": "You can only make 100 requests per second",
"status": 429
}{
"code": "UNKNOWN_ERROR",
"message": "Internal server error",
"status": 500
}Authorizations
Your Periskope API token, sent as Authorization: Bearer <token>. Generate one from the Periskope dashboard under Settings → API & Webhooks. API access requires an active Pro or Enterprise plan.
Path Parameters
The context_id of the FAQ
1"00000000-0000-0000-0000-000000000000"
Body
The updated question. question and answer must be sent together — sending them fully replaces the FAQ text and regenerates its embedding.
1"What is Periskope?"
The updated answer. Must be sent together with question.
1"Periskope is a platform to manage WhatsApp at scale."
Replaces the attachments stored on the FAQ. When question and answer are sent, omitting this field clears any existing attachments; on a partial update (no question/answer) omitting it leaves them unchanged.
[]
Set the activation state of the FAQ. Omit to leave it unchanged.
true
Response
An array containing the updated FAQ entry
Unique id of the knowledge-base entry. For FAQs, this is the id to use with the GET/PATCH/DELETE /knowledge-base/faq/{context_id} routes. Each chunk of an uploaded document has its own context_id.
"00000000-0000-0000-0000-000000000000"
Id of the organization the entry belongs to
"00000000-0000-0000-0000-000000000000"
The question the entry answers. For document chunks this is a derived heading — the document title plus the detected section or question (e.g. "product-faq — Pricing").
"What is Periskope?"
The answer text the AI agent draws on. For document chunks, the extracted text of the chunk.
"Periskope is a platform to manage WhatsApp at scale."
Kind of entry: 'faq' for question/answer pairs created via the API or dashboard, 'document' for chunks extracted from uploaded PDF documents, 'self-learned' for entries the AI agent captured automatically from conversations.
faq, document, self-learned "faq"
Vector embedding of the entry, serialized as a string. Used internally for semantic retrieval — safe to ignore.
"[-0.0123,0.0456,0.0789,...]"
Attachments stored on the entry — for FAQs created with an attachment, an array of { link: { url, type, name } } objects pointing at the stored file. null or an empty array when the entry has no attachments.
[
{
"link": {
"url": "org-assets/00000000-0000-0000-0000-000000000000/ai_assets/00000000-0000-0000-0000-000000000000/pricing.pdf",
"type": "application/pdf",
"name": "pricing.pdf"
}
}
]
Average rating of AI answers generated from this entry. null when the entry has not been rated.
null
Id of the uploaded document a chunk belongs to — use it with the GET/DELETE /knowledge-base/document/{document_id} routes. null for FAQs and self-learned entries.
"00000000-0000-0000-0000-000000000000"
Whether the entry is currently used by the AI agent when answering. Entries created via the API start inactive unless is_active is sent as true.
true
Extra metadata about the entry. For document chunks: fileName, filePath, chunkIndex, tokenCount and the extraction source ('qa' for detected Q&A pairs, 'paragraph' for paragraph blocks, 'text' for sentence windows). null for FAQs.
{
"fileName": "product-faq.pdf",
"chunkIndex": 1,
"tokenCount": 180,
"source": "qa"
}
Tags assigned to the entry. null when untagged.
null
When the entry was created, as an ISO 8601 timestamp
"2026-01-15T09:30:00.000Z"
When the entry was last updated, as an ISO 8601 timestamp. null when never updated.
"2026-01-15T09:30:00.000Z"
Was this page helpful?