message.comDevelopers

Knowledge base Planned

The knowledge base grounds AI replies in your own content. Add a URL, we crawl up to two levels deep (typically 50 to 200 pages), chunk the text, embed each chunk with our self-hosted embeddings model, and store the vectors in our vector store. Used by Smart Hold, AI Receptionist, and agent assist for retrieval-augmented generation.

This endpoint is on the roadmap (Phase B, after the AI substrate ships). The surface here is the committed shape; details may move before launch.

Sources

A source is one starting URL plus the recursive pages we discover. Sources are workspace-scoped; chunks belong to sources.

List sources

GET/api/v1/kb/sourcesAuth: Bearer

Code samples

cURL
curl 'https://app.message.com/api/v1/kb/sources' \
  -H 'Authorization: Bearer YOUR_WORKSPACE_JWT'
JavaScript
const res = await fetch('https://app.message.com/api/v1/kb/sources', {
  headers: { Authorization: 'Bearer ' + token }
});
const { sources } = await res.json();
Python
import requests
r = requests.get(
    "https://app.message.com/api/v1/kb/sources",
    headers={"Authorization": f"Bearer {token}"},
)
sources = r.json()["sources"]
Ruby
require "net/http"
require "json"
uri = URI("https://app.message.com/api/v1/kb/sources")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
  req = Net::HTTP::Get.new(uri)
  req["Authorization"] = "Bearer #{token}"
  http.request(req)
end
sources = JSON.parse(res.body)["sources"]
PHP
<?php
$ctx = stream_context_create([
  "http" => ["method" => "GET", "header" => "Authorization: Bearer $token"]
]);
$sources = json_decode(file_get_contents("https://app.message.com/api/v1/kb/sources", false, $ctx), true)["sources"];

Add a source

POST/api/v1/kb/sourcesAuth: Bearer

Starts a crawl. Returns the source record with status: crawling; flips to ready when embeddings are computed.

FieldTypeDescription
urlrequiredstringStart URL. We crawl this domain only, up to 2 levels deep.
nameoptionalstringDisplay name. Defaults to the page title at the start URL.
maxPagesoptionalintegerCap on pages crawled. Defaults to 200, maximum 1000.
respectRobotsTxtoptionalbooleanHonour robots.txt. Defaults to true; set false only for first-party domains you own.
200 OK
{
  "id": "uuid",
  "name": "Acme docs",
  "url": "https://docs.acme.com",
  "status": "ready",
  "chunkCount": 1432,
  "lastCrawledAt": "2026-05-13T15:00:00Z",
  "createdAt": "2026-05-10T12:00:00Z"
}

Refresh a source

POST/api/v1/kb/sources/:id/recrawlAuth: Bearer

Forces a fresh crawl. New chunks replace old chunks under the same source ID.

Delete a source

DELETE/api/v1/kb/sources/:idAuth: Bearer

Removes the source and all its chunks from the vector store.

POST/api/v1/kb/searchAuth: Bearer

Run a semantic search across all chunks in the workspace. Embeds the query, runs cosine-similarity search over the vector store, returns the top-K chunks. Used by AI features internally; exposed for custom UIs.

Body
{
  "query": "How do I cancel a subscription?",
  "topK": 5
}
200 OK
{
  "results": [
    {
      "chunkId": "uuid",
      "sourceId": "uuid",
      "url": "https://docs.acme.com/billing/cancel",
      "text": "To cancel your subscription, visit...",
      "score": 0.82
    }
  ]
}

Chunks

GET/api/v1/kb/sources/:id/chunksAuth: Bearer

List the chunks in a source. Cursor-paginated. Used for spot-checking that the right content was indexed.

Errors

CodeWhen
400 invalid_urlURL did not parse or scheme is not https.
402 plan_limitWorkspace plan does not include AI / KB features.
422 crawl_blockedrobots.txt disallows; you can override with respectRobotsTxt: false on first-party domains.

Common pitfalls

  • Pointing at a help-center hosted on a different domain. Crawls stay within one apex. Add the help-center as a separate source.
  • Indexing a constantly-changing site without recrawling. Default cadence is weekly. Bump it via PATCH for high-churn docs.
  • Searching without grounding. The search endpoint returns chunks; combining those chunks with an LLM is the AI engagement. See RAG concept.