Skip to main content

🧠 Intellect Service

The intellect configuration is the AI brain behind your agent — it defines what the assistant knows, how it speaks, and what it can do.

When you create an agent with intellectType: 'genie', the configId field references an intellect managed by this service. Use the Intellect Service to create, retrieve, and customize that configuration: tuning the assistant's persona, attaching a knowledge base, adding a glossary, restricting topics, and toggling capabilities.

Base route: POST /v1/intellect/{action}

Two intellect types
  • internal — Kaltura's built-in Genie AI engine. Supports full configuration: prompts, glossary, knowledge base, capabilities, tools.
  • external — An external LLM endpoint (e.g. OpenAI-compatible). Requires a url and protocol. Limited configuration options.

Data Model

Intellect (internal)

FieldTypeDescription
idnumberServer-assigned Intellect ID — used as configId in the Agent service
type'internal'Always internal for Genie-backed intellects
namestringHuman-readable display name
descriptionstringOptional free-text description
status0 | 1 | 2Lifecycle status (0 = inactive, 1 = active, 2 = archived)
partner_idnumberKaltura partner ID
user_idstringID of the user who created this intellect
base_directivestringCore system-prompt directive defining the agent's persona
promptsobject[]Custom prompt templates (see Prompts)
glossarystringDomain-specific vocabulary injected into the system prompt
knowledge_idsnumber[]IDs of Knowledge records attached (max 1 currently)
capabilitiesobjectFeature flags per capability (see Capabilities)
toolsobjectNamed tool configurations (API, code, or CSV tools)
allow_client_variablesbooleanWhether the client can inject runtime variables into prompt templates (default: true)
tagsstring[]Searchable tags for filtering
secretsobjectNamed secrets stored encrypted — values are masked as *** on read
created_atstring (ISO date)Creation timestamp
updated_atstring (ISO date)Last modified timestamp

ExternalIntellect

FieldTypeDescription
idnumberServer-assigned Intellect ID
type'external'Always external
namestringHuman-readable display name
urlstringURL of the external assistant endpoint
protocolstringProtocol identifier (e.g. 'openai-compatible', 'text_agent')
status0 | 1 | 2Lifecycle status
tagsstring[]Searchable tags
created_at / updated_atstringTimestamps

Prompts

Custom prompts shape the assistant's persona by overriding specific system prompt slots:

keylabelheaderTemplateDescription
goalGoalYour main goal is:The assistant's primary objective
targetAudienceTarget AudienceYour target audience is:Who the assistant is designed for
restrictedTopicsRestricted TopicsThese are comma separated restricted topics, do not talk about them:Topics to avoid
namenameYou will be identified as this name, this is your name:The assistant's name

Each prompt object requires: key, label, headerTemplate, type (always "custom"), value.

Capabilities

CapabilityValuesDescription
use_knowledge_baseon | off | disabledUse attached knowledge base content in responses
use_content_searchon | off | disabledSearch for relevant video/media content
use_get_entry_contenton | off | disabledRead and summarise specific Kaltura entries
generate_followup_questionson | off | disabledSuggest follow-up questions after responses
include_sourceson | off | disabledInclude source references in answers
use_related_fileson | off | disabledUse attached/related files as context
avataron | off | disabledEnable avatar mode for this intellect

Actions

add — Create an Intellect

POST /v1/intellect/add

Request body (internal):

{
"type": "internal",
"name": "Video Solutions Advisor",
"description": "An AI assistant that helps users explore Kaltura's video platform",
"status": 1,
"base_directive": "You are a helpful video platform assistant.",
"prompts": [
{
"key": "name",
"label": "name",
"headerTemplate": "You will be identified as this name, this is your name:",
"type": "custom",
"value": "Kali"
},
{
"key": "goal",
"label": "Goal",
"headerTemplate": "Your main goal is:",
"type": "custom",
"value": "Help users find and watch video content."
},
{
"key": "restrictedTopics",
"label": "Restricted Topics",
"headerTemplate": "These are comma separated restricted topics, do not talk about them:",
"type": "custom",
"value": "competitor pricing, unsupported features"
}
],
"glossary": "VOD: Video on Demand\nOTT: Over-the-top streaming",
"tags": ["production"],
"capabilities": {
"use_knowledge_base": "on",
"use_content_search": "on",
"avatar": "on"
}
}
FieldTypeRequiredDescription
type'internal' | 'external'✅ YesIntellect type
namestringNoDisplay name
descriptionstringNoFree-text description
statusnumberNo0/1/2 (default: 1)
base_directivestringNoCore system prompt
promptsobject[]NoCustom prompt templates
glossarystringNoDomain vocabulary
knowledge_idsnumber[]NoKnowledge record IDs to attach (max 1)
capabilitiesobjectNoFeature flags
toolsobjectNoTool configurations
tagsstring[]NoSearchable tags
allow_client_variablesbooleanNoAllow runtime variable injection (default: true)

Response: Returns the created Intellect object with generated id.

Examples:

cURL
curl -X POST "https://YOUR_API_HOST/v1/intellect/add" \
-H "Authorization: KS YOUR_KS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "internal",
"name": "Kali",
"status": 1,
"prompts": [
{
"key": "name", "label": "name",
"headerTemplate": "You will be identified as this name, this is your name:",
"type": "custom", "value": "Kali"
},
{
"key": "goal", "label": "Goal",
"headerTemplate": "Your main goal is:",
"type": "custom", "value": "Help users find and watch video content."
}
]
}'
JavaScript
const intellect = await fetch('https://YOUR_API_HOST/v1/intellect/add', {
method: 'POST',
headers: {
Authorization: `KS ${ksToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'internal',
name: 'Kali',
status: 1,
prompts: [
{
key: 'name',
label: 'name',
headerTemplate: 'You will be identified as this name, this is your name:',
type: 'custom',
value: 'Kali',
},
{
key: 'goal',
label: 'Goal',
headerTemplate: 'Your main goal is:',
type: 'custom',
value: 'Help users find and watch video content.',
},
],
glossary: 'VOD: Video on Demand\nOTT: Over-the-top streaming',
}),
}).then((res) => res.json());

// Use intellect.id as configId when creating an agent
console.log(`Created intellect: ${intellect.id}`);

get — Retrieve an Intellect

POST /v1/intellect/get

Request body:

{ "id": 42 }
FieldTypeRequiredDescription
idnumber✅ YesThe intellect ID to retrieve

Response: Returns the full Intellect or ExternalIntellect object.

Examples:

cURL
curl -X POST "https://YOUR_API_HOST/v1/intellect/get" \
-H "Authorization: KS YOUR_KS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "id": 42 }'
JavaScript
const intellect = await fetch('https://YOUR_API_HOST/v1/intellect/get', {
method: 'POST',
headers: { Authorization: `KS ${ksToken}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ id: 42 }),
}).then((res) => res.json());

list — List Intellects

POST /v1/intellect/list

Request body:

{
"filter": {
"objectType": "IntellectListFilter",
"typeEquals": "internal",
"statusEquals": 1,
"nameLike": "Video",
"orderBy": "-createdAt"
},
"pager": {
"pageIndex": 1,
"pageSize": 30
}
}
FieldTypeDescription
filter.objectType'IntellectListFilter'Required discriminator
filter.typeEquals'internal' | 'external'Filter by type
filter.statusEqualsnumberFilter by exact status
filter.statusInnumber[]Filter by status list
filter.nameLikestringPartial, case-insensitive name match
filter.nameEqualsstringExact name match
filter.idEqualsnumberMatch a single ID
filter.idsInnumber[]Match multiple IDs
filter.tagsContainsstringFilter by tag
filter.orderBystring+createdAt, -createdAt, +updatedAt, -updatedAt
pager.pageIndexnumber1-based page number (default: 1)
pager.pageSizenumberResults per page, max 500 (default: 30)

Response:

{
"totalCount": 5,
"objects": [ ... ]
}

Example:

JavaScript — list all active internal intellects
const { objects, totalCount } = await fetch('https://YOUR_API_HOST/v1/intellect/list', {
method: 'POST',
headers: { Authorization: `KS ${ksToken}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
filter: { objectType: 'IntellectListFilter', typeEquals: 'internal', statusEquals: 1 },
pager: { pageIndex: 1, pageSize: 30 },
}),
}).then((res) => res.json());

console.log(`Found ${totalCount} active intellects`);

update — Update an Intellect

POST /v1/intellect/update

Update fields on an existing intellect. Only fields present in the request are changed.

Request body:

{
"type": "internal",
"id": 42,
"name": "Kali (Updated)",
"prompts": [
{
"key": "name",
"label": "name",
"headerTemplate": "You will be identified as this name, this is your name:",
"type": "custom",
"value": "Kali"
},
{
"key": "goal",
"label": "Goal",
"headerTemplate": "Your main goal is:",
"type": "custom",
"value": "Updated goal text."
}
],
"glossary": "VOD: Video on Demand\nLive: Live streaming"
}
FieldTypeRequiredDescription
type'internal' | 'external'✅ YesMust match the existing intellect type
idnumber✅ YesThe intellect to update
namestringNoNew display name
base_directivestringNoUpdated core system prompt
promptsobject[]NoReplaces all existing prompts
glossarystringNoReplaces existing glossary
knowledge_idsnumber[]NoReplaces knowledge attachments (max 1)
capabilitiesobjectNoUpdated capability flags
statusnumberNoUpdated lifecycle status
tagsstring[]NoReplaces tag list
Arrays are replaced, not merged

prompts, tags, and knowledge_ids are fully replaced when provided. Fetch the current intellect first to preserve existing values.

Examples:

cURL — safely update one prompt key
# Fetch current first, then update with merged prompts
curl -X POST "https://YOUR_API_HOST/v1/intellect/update" \
-H "Authorization: KS YOUR_KS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "internal",
"id": 42,
"name": "Kali (Updated)"
}'
JavaScript — safely patch one prompt
const current = await fetch('https://YOUR_API_HOST/v1/intellect/get', {
method: 'POST',
headers: { Authorization: `KS ${ksToken}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ id: 42 }),
}).then((res) => res.json());

// Merge: replace 'name' prompt, keep everything else
const updatedPrompts = [
...current.prompts.filter((p) => p.key !== 'name'),
{
key: 'name',
label: 'name',
headerTemplate: 'You will be identified as this name, this is your name:',
type: 'custom',
value: 'Kali v2',
},
];

await fetch('https://YOUR_API_HOST/v1/intellect/update', {
method: 'POST',
headers: { Authorization: `KS ${ksToken}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'internal', id: 42, prompts: updatedPrompts }),
}).then((res) => res.json());

delete — Delete an Intellect

POST /v1/intellect/delete

Permanently deletes an intellect. This cannot be undone.

Request body:

{ "id": 42 }
FieldTypeRequiredDescription
idnumber✅ YesThe intellect to delete

Example:

cURL
curl -X POST "https://YOUR_API_HOST/v1/intellect/delete" \
-H "Authorization: KS YOUR_KS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "id": 42 }'

How Intellect Connects to Agents

The id returned here is what you use as configId when creating or updating an agent:

{
"intellect": {
"intellectType": "genie",
"genieId": "YOUR_GENIE_ID",
"configId": 42
}
}

See 🤖 Agent Service for full agent configuration details.

Next Steps

  • 📚 Knowledge Service — Create and manage knowledge bases to attach via knowledge_ids
  • 🤖 Agent Service — Wire this intellect to an agent via configId
  • 🛠️ Workflows — End-to-end agent setup