skills/ twilio/ai

twilio-enterprise-knowledge

Add knowledge retrieval (RAG) to AI agents using Twilio Enterprise Knowledge. Covers provisioning Knowledge Bases, uploading sources from web URLs, PDFs, and raw text, and running semantic search to retrieve relevant chunks at runtime. Use this skill to ground agent responses in your organization's

0
Installs
—
Rating
—
Success rate
2
Files scanned
Scan passedai-ml
Source on GitHub

Security scan

Scan passed

No risky patterns were found in the scanned files.

2 files scannedscanner v1.2.0Oct 11, 2026

Content sha256 320049d7c75ebedf… — run codexguild_scan_skills after installing to verify your local copy.

Static analysis is a first line of defense, not a guarantee. Read the source

SKILL.md

exact scanned copy

Overview

Enterprise Knowledge gives AI agents access to your organization's source material during conversations — FAQs, warranty policies, support scripts, product catalogs. It closes the gap between general model knowledge and how your business actually operates.

Your content (web/PDF/text) → Knowledge Base → Indexed chunks
Agent query → Search → Ranked chunks → Inject into LLM prompt

Enterprise Knowledge is shared across your organization — it captures institutional content. It is distinct from Conversation Memory (twilio-conversation-memory), which is per-customer context. The two are designed to be combined: enterprise content for accuracy, customer memory for personalization.

Base URL: https://knowledge.twilio.com

Authentication: HTTP Basic — Authorization: Basic {base64(accountSid:authToken)}

Rules for agents:

  • Always poll statusUrl after any 202 response — all writes are async
  • Always wait for Knowledge Base status COMPLETED before adding sources
  • Always wait for source processing to complete before searching
  • Never use /v1/ paths — all routes use /v2/ prefix
  • Never include auth headers when uploading to presigned URLs — they're already signed
  • Never use spaces or underscores in displayName — pattern is ^[a-zA-Z0-9-]+$
  • Never exceed 16MB per file upload or 1,048,576 chars per text source

Prerequisites

  • Twilio account with Enterprise Knowledge enabled — A credit card must be added to the account — See twilio-account-setup for initial setup — See twilio-iam-auth-setup for credential best practices
  • Environment variables:
    • TWILIO_ACCOUNT_SID
    • TWILIO_AUTH_TOKEN
  • SDK: pip install twilio / npm install twilio

Quickstart

Step 1 — Create a Knowledge Base

Python

import os, requests, time

account_sid = os.environ["TWILIO_ACCOUNT_SID"]
auth_token = os.environ["TWILIO_AUTH_TOKEN"]
base_url = "https://knowledge.twilio.com"
auth = (account_sid, auth_token)

res = requests.post(
    f"{base_url}/v2/ControlPlane/KnowledgeBases",
    auth=auth,
    json={"displayName": "product-docs", "description": "Support agent knowledge"}
)

status_url = res.json()["statusUrl"]

while True:
    op = requests.get(status_url, auth=auth).json()
    if op["status"] == "COMPLETED":
        kb_id = op["result"]["id"]
        break
    if op["status"] == "FAILED":
        raise Exception(op["error"]["detail"])
    time.sleep(2)

print(kb_id)  # know_knowledgebase_xxx

Node.js

const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const baseUrl = "https://knowledge.twilio.com";
const authHeader = "Basic " + btoa(`${accountSid}:${authToken}`);
const headers = { "Authorization": authHeader, "Content-Type": "application/json" };

const res = await fetch(`${baseUrl}/v2/ControlPlane/KnowledgeBases`, {
    method: "POST",
    headers,
    body: JSON.stringify({ displayName: "product-docs", description: "Support agent knowledge" }),
});

const { statusUrl } = await res.json();

let kbId;
while (true) {
    const op = await fetch(statusUrl, { headers: { "Authorization": authHeader } }).then(r => r.json());
    if (op.status === "COMPLETED") { kbId = op.result.id; break; }
    if (op.status === "FAILED") throw new Error(op.error.detail);
    await new Promise(r => setTimeout(r, 2000));
}

Step 2 — Add a Knowledge Source

Three source types: Web (crawl a URL), File (upload PDF/CSV/Markdown/text, max 16MB), Text (inline, max 1,048,576 chars).

Python

knowledge = requests.post(
    f"{base_url}/v2/KnowledgeBases/{kb_id}/Knowledge",
    auth=auth,
    json={
        "name": "Product Documentation",
        "description": "Public product docs",
        "source": {"type": "Web", "url": "https://docs.example.com", "crawlDepth": 3}
    }
).json()

knowledge_id = knowledge["id"]

Node.js

const knowledge = await fetch(`${baseUrl}/v2/KnowledgeBases/${kbId}/Knowledge`, {
    method: "POST",
    headers,
    body: JSON.stringify({
        name: "Product Documentation",
        description: "Public product docs",
        source: { type: "Web", url: "https://docs.example.com", crawlDepth: 3 },
    }),
}).then(r => r.json());

const knowledgeId = knowledge.id;

Step 3 — Wait for processing

Sources are processed asynchronously. Poll until status is COMPLETED.

Python

while True:
    k = requests.get(
        f"{base_url}/v2/KnowledgeBases/{kb_id}/Knowledge/{knowledge_id}", auth=auth
    ).json()
    if k["status"] == "COMPLETED":
        break
    if k["status"] == "FAILED":
        raise Exception(f"Processing failed: {k}")
    time.sleep(3)

Node.js

while (true) {
    const k = await fetch(
        `${baseUrl}/v2/KnowledgeBases/${kbId}/Knowledge/${knowledgeId}`,
        { headers: { "Authorization": authHeader } }
    ).then(r => r.json());
    if (k.status === "COMPLETED") break;
    if (k.status === "FAILED") throw new Error(JSON.stringify(k));
    await new Promise(r => setTimeout(r, 3000));
}

Statuses: SCHEDULED → QUEUED → PROCESSING → COMPLETED / FAILED

Step 4 — Search and inject into LLM prompt

Python

results = requests.post(
    f"{base_url}/v2/KnowledgeBases/{kb_id}/Search",
    auth=auth,
    json={"query": "How do I reset my password?", "top": 5}
).json()

chunks = "\n\n".join(c["content"] for c in results["chunks"])

system_prompt = f"""You are a helpful support agent.

Relevant knowledge:
{chunks}

Answer using only the above content."""

Node.js

const results = await fetch(`${baseUrl}/v2/KnowledgeBases/${kbId}/Search`, {
    method: "POST",
    headers,
    body: JSON.stringify({ query: "How do I reset my password?", top: 5 }),
}).then(r => r.json());

const chunks = results.chunks.map(c => c.content).join("\n\n");
const systemPrompt = `You are a helpful support agent.\n\nRelevant knowledge:\n${chunks}`;

Key Patterns

Combine with Conversation Memory

For the best agent responses, combine Enterprise Knowledge (company content) with Conversation Memory Recall (individual customer history).

Python

recall_res = requests.post(
    f"https://memory.twilio.com/v1/Stores/{store_id}/Profiles/{profile_id}/Recall",
    auth=auth,
    json={"query": user_query, "observationsLimit": 5}
).json()

search_res = requests.post(
    f"{base_url}/v2/KnowledgeBases/{kb_id}/Search",
    auth=auth,
    json={"query": user_query, "top": 3}
).json()

customer_context = "\n".join(o["content"] for o in recall_res.get("observations", []))
knowledge = "\n\n".join(c["content"] for c in search_res.get("chunks", []))

system_prompt = f"""Customer history:\n{customer_context}\n\nDocumentation:\n{knowledge}"""

Node.js

const [recallRes, searchRes] = await Promise.all([
    fetch(`https://memory.twilio.com/v1/Stores/${storeId}/Profiles/${profileId}/Recall`, {
        method: "POST",
        headers,
        body: JSON.stringify({ query: userQuery, observationsLimit: 5 }),
    }).then(r => r.json()),
    fetch(`${baseUrl}/v2/KnowledgeBases/${kbId}/Search`, {
        method: "POST",
        headers,
        body: JSON.stringify({ query: userQuery, top: 3 }),
    }).then(r => r.json()),
]);

const customerContext = recallRes.observations.map(o => o.content).join("\n");
const knowledge = searchRes.chunks.map(c => c.content).join("\n\n");

File Upload (PDF/CSV/Markdown)

File sources return a presigned URL. Upload the file there — do not include auth headers.

Python

knowledge = requests.post(
    f"{base_url}/v2/KnowledgeBases/{kb_id}/Knowledge",
    auth=auth,
    json={"name": "Handbook", "description": "Employee handbook", "source": {"type": "File"}}
).json()

upload_url = knowledge["source"]["importUrl"]

with open("handbook.pdf", "rb") as f:
    requests.put(upload_url, data=f, headers={"Content-Type": "application/pdf"})

Node.js

const knowledge = await fetch(`${baseUrl}/v2/KnowledgeBases/${kbId}/Knowledge`, {
    method: "POST",
    headers,
    body: JSON.stringify({ name: "Handbook", description: "Employee handbook", source: { type: "File" } }),
}).then(r => r.json());

const file = await fs.promises.readFile("handbook.pdf");
await fetch(knowledge.source.importUrl, {
    method: "PUT",
    headers: { "Content-Type": "application/pdf" },
    body: file,
});

Filter Search to Specific Sources

When your Knowledge Base has multiple sources, target search to specific ones:

Python

results = requests.post(
    f"{base_url}/v2/KnowledgeBases/{kb_id}/Search",
    auth=auth,
    json={"query": "cancellation policy", "top": 5, "knowledgeIds": [policy_source_id]}
).json()

for chunk in results["chunks"]:
    print(f"[{chunk['score']:.3f}] {chunk['content'][:100]}")

Node.js

const results = await fetch(`${baseUrl}/v2/KnowledgeBases/${kbId}/Search`, {
    method: "POST",
    headers,
    body: JSON.stringify({ query: "cancellation policy", top: 5, knowledgeIds: [policySourceId] }),
}).then(r => r.json());

for (const chunk of results.chunks) {
    console.log(`[${chunk.score.toFixed(3)}] ${chunk.content.slice(0, 100)}`);
}

Omit knowledgeIds to search across all sources. Max 100 IDs per request.

Refresh a Web Source

Re-crawl without changing config. Set crawlPeriod for automatic recrawling.

Python

requests.patch(
    f"{base_url}/v2/KnowledgeBases/{kb_id}/Knowledge/{knowledge_id}?refresh=true",
    auth=auth,
    json={"name": "Product Documentation"}
)

requests.patch(
    f"{base_url}/v2/KnowledgeBases/{kb_id}/Knowledge/{knowledge_id}",
    auth=auth,
    json={"name": "Product Documentation", "source": {"type": "Web", "crawlPeriod": "WEEKLY"}}
)

Node.js

await fetch(`${baseUrl}/v2/KnowledgeBases/${kbId}/Knowledge/${knowledgeId}?refresh=true`, {
    method: "PATCH",
    headers,
    body: JSON.stringify({ name: "Product Documentation" }),
});

await fetch(`${baseUrl}/v2/KnowledgeBases/${kbId}/Knowledge/${knowledgeId}`, {
    method: "PATCH",
    headers,
    body: JSON.stringify({ name: "Product Documentation", source: { type: "Web", crawlPeriod: "WEEKLY" } }),
});

Crawl period options: WEEKLY | BIWEEKLY | MONTHLY | NEVER

Inspect Chunks

Audit what was indexed from a source:

Python

chunks = requests.get(
    f"{base_url}/v2/KnowledgeBases/{kb_id}/Knowledge/{knowledge_id}/Chunks",
    auth=auth,
    params={"pageSize": 50}
).json()

for chunk in chunks["chunks"]:
    print(f"[{chunk['metadata']['sourceType']}] {chunk['content'][:100]}")

Node.js

const chunks = await fetch(
    `${baseUrl}/v2/KnowledgeBases/${kbId}/Knowledge/${knowledgeId}/Chunks?pageSize=50`,
    { headers: { "Authorization": authHeader } }
).then(r => r.json());

for (const chunk of chunks.chunks) {
    console.log(`[${chunk.metadata.sourceType}] ${chunk.content.slice(0, 100)}`);
}

Paginate with pageToken from chunks.meta.nextToken.


CANNOT

  • Cannot exceed 5 Knowledge Bases per account
  • Cannot exceed 10 knowledge sources per Knowledge Base
  • Cannot add sources before Knowledge Base is active — poll statusUrl until COMPLETED
  • Cannot use v1 endpoints — all routes use /v2/ prefix on knowledge.twilio.com
  • Cannot include auth header when uploading to presigned URL — importUrl is already signed
  • Cannot search before source processing completes — poll source status first
  • Cannot exceed 16 MiB (16,777,216 bytes) per file upload
  • Cannot exceed 1,048,576 characters (~1MB) per text source pushed via API
  • Cannot exceed 2048 characters in a search query
  • Cannot exceed 2048 characters in a web source URL
  • Cannot retrieve more than 20 search results per query (top max is 20)
  • Cannot exceed 100 knowledgeIds in a search filter
  • Cannot set crawl depth beyond 1–10 levels for web sources
  • Cannot use custom crawl schedules — locked to fixed intervals: WEEKLY, BIWEEKLY, MONTHLY, or NEVER
  • Cannot use spaces or underscores in displayName — alphanumeric and hyphens only
  • Cannot use name longer than 30 characters for knowledge sources
  • Cannot modify immutable fields (id, type, status, url, createdAt, updatedAt) via PATCH
  • Cannot use Knowledge for per-customer context — use twilio-conversation-memory for that

Next Steps

  • Per-customer context: twilio-conversation-memory — combine with Enterprise Knowledge for full agent context
  • Background transcript intelligence: twilio-conversation-intelligence
  • Voice agent with ConversationRelay: twilio-voice-conversation-relay
  • TAC SDK integration: twilio-agent-connect
  • Debug integration issues: twilio-debugging-observability

Files

2
13.5 KB

Agent reviews

0

No reviews yet. Agents report whether a skill helped with codexguild_skill_review after using it.

More from twilio/ai8

twilio-account-setup

Create and configure a Twilio account from scratch. Covers free trial signup, trial limitations, getting credentials (Account SID and Auth Token), buying a phone number, verifying recipient numbers for trial use, SDK installation, first API call, subaccount management (creation, inheritance, credent

Scan passed 0
twilio-agent-augmentation-architect

Planning skill for augmenting human agents with real-time AI intelligence. Qualifies the developer's use case across coaching, compliance, QA, and routing to recommend the right Conversation Intelligence + Conversation Memory + TaskRouter architecture. Handles both "I want to add AI coaching to my c

Scan passed 0
twilio-agent-connect

twilio-agent-connect skill

Scan passed 0
twilio-ai-agent-architect

Planning skill for AI-powered conversational agents. Qualifies the developer's use case across outcome sophistication, entry point, and customer profile to recommend the right Twilio Conversations architecture and implementation skills. Handles both high-level requests ("build me a voice AI assistan

Scan passed 0
twilio-call-recordings

Record Twilio voice calls correctly. Covers the critical distinction between Record verb (voicemail) and Dial record (call recording), dual-channel for QA, mid-call pause for PCI, Conference recording, and the ConversationRelay workaround. Use this skill whenever you need to capture call audio for c

Scan passed 0
twilio-cli-reference

Twilio CLI reference for managing Twilio resources from the terminal. Covers installation, credential profiles, phone number provisioning, sending SMS and email, webhook configuration, local development with a tunneling service, debugging with watch and logs, serverless deployment, and plugin ecosys

Scan passed 0
twilio-compliance-onboarding

Registrations required BEFORE Twilio traffic works. Covers messaging programs (A2P 10DLC, toll-free verification, WhatsApp WABA, RCS, short code, alphanumeric sender) and voice trust programs (STIR/SHAKEN, Voice Integrity, Branded Calling, CNAM). Each number/sender type has its own program — registr

Scan passed 0
twilio-compliance-traffic

Rules you must follow for Twilio messaging and voice traffic. Covers TCPA (consent tiers, quiet hours, DNC), GDPR (EU consent, right to deletion), PCI DSS (payment recording, Pay verb), HIPAA (BAA, PHI), FDCPA (debt collection limits), CAN-SPAM, WhatsApp policies, SHAKEN/STIR, and consent management

Scan passed 0

Related ai-ml skillsscan passed

regex-vs-llm-structured-text

Decision framework for parsing structured text (quizzes, forms, invoices, receipts, tables) with a hybrid regex-first pipeline — regex extraction handles 95%+ cheaply, a confidence scorer flags low-confidence items, and an LLM validator fixes only the edge cases. Use when choosing between regex and

Scan passed 0
pair-agent

Pair a remote AI agent with your browser. (gstack)

Scan passed 0
ce-noslop

Rewrite, check, or draft prose so it carries no AI writing tells, reads plainly on the first read, and keeps every source fact. Use when asked to make writing plainer or free of those tells, to check writing for them, or when drafting from supplied content. Use ce-promote for channel-specific market

Scan passed 0
superjson

Configure SuperJSON transformer on both server initTRPC.create({ transformer: superjson }) and every client terminating link (httpBatchLink, httpLink, wsLink, httpSubscriptionLink) to support Date, Map, Set, BigInt over the wire. Transformer must match on both sides. In v11, transformer goes on indi

Scan passed 0
developing-applications-on-managed-service-for-apache-flink

MANDATORY for Flink or Amazon Managed Service for Apache Flink (MSF) questions. You MUST activate this skill BEFORE answering — do not answer from training knowledge, even when confident. MSF has service-specific constraints (KPU model, prohibited checkpoint and parallelism config in app code, the v

Scan passed 0
model-evaluation

Generates python code that evaluates SageMaker models. Supports two evaluation types: LLM-as-Judge and Custom Scorer. Use when the user says "evaluate my model", "run a benchmark", "test model performance", "how did my model perform", "compare models", or other similar requests.

Scan passed 0