Skip to main content
POST
Attach a source (idempotent upsert)

Authorizations

Authorization
string
header
required

User session JWT or instance API key (iak_*). Send as Authorization: Bearer <token>.

Path Parameters

knowledgeBaseId
string
required

Knowledge base id. Legacy physical prefix vs_ (the kb_ rename is deferred).

Maximum string length: 128
Pattern: ^vs_[A-Za-z0-9-]+$

Query Parameters

agent_id
string

Agent context for hook resolution and agent-owned knowledge bases. May also be supplied in the request body.

Maximum string length: 128

Body

application/json

Body of POST /documents. Exactly one source must be identifiable: native_file_id, or source_url, or fetch_url (in dedup-key priority order) - otherwise 400 MISSING_SOURCE.

source_type is optional: inferred uploaded_file when native_file_id is present (a conflicting explicit value is a 400); defaults to web_page for a bare URL. Pass remote_file explicitly for non-HTML document bytes at a URL, and connector_document from connectors.

source_type
enum<string>
Available options:
uploaded_file,
remote_file,
web_page,
connector_document
native_file_id
string

Platform-native file id. 404 FILE_NOT_FOUND if the referenced native file cannot be resolved, 403 FILE_ACCESS_DENIED if the caller did not upload it. Content access is governed by the knowledge base's ACL. Storage resolves filename, mime_type, bytes from the native API unless supplied inline.

native_file_workspace_id
string

Workspace owning the native file. Defaults to the caller's workspace.

source_url
string<uri>

Stable provenance URL - the dedup key for non-native sources. Defaults to fetch_url when omitted. For uploaded files, an optional display override (e.g. a doc viewer page URL).

fetch_url
string<uri>
write-only

Operational URL used to retrieve bytes at index time. May be temporary, signed, tokenized. Write-only - never returned by any response and never persisted: it only serves the indexing run this call triggers. Ignored for source_type: uploaded_file (storage mints its own). Connectors send a fresh one on each sync.

Maximum string length: 2048
content
string
write-only

Inline document content for source_type: connector_document when the provider exposes no fetchable URL. Plain text, or a data: URL for binary bytes. Takes precedence over fetch_url; storage copies it into its own files registry before indexing. Write-only, never returned.

Maximum string length: 2000000
filename
string
Maximum string length: 512
mime_type
string
bytes
integer
Required range: x >= 0
chunking_strategy
object

Per-document override of the knowledge base chunking. Omit to follow the knowledge base. type is one of auto, fixed, sentence, paragraph (static is an alias of paragraph) or semantic. The reserved {"type": "default"} is rejected here (400 VALIDATION_ERROR).

model
string

Optional embedding model override threaded into the indexing pipeline for this document.

Maximum string length: 256
agent_id
string

Agent context for hook resolution and agent-owned knowledge bases. May also be supplied as the agent_id query parameter.

Maximum string length: 128
scope
enum<string>
default:knowledge
Available options:
knowledge,
conversation
conversation_id
string
expires_at
integer

Unix seconds.

tags
object
metadata
object
hooks
object[]
write-only

Optional external-hook pass-through (e.g. from agent-factory). Merged with the server-resolved platform/org/agent hook config. A before_file_ingest or after_file_parse hook may transform or block the content; a block yields 403 HOOK_REJECTED (sync) or a document failed with last_error.code: HookRejected (async), with rejected_by and public_rejection_reason set (the latter only when the hook sets expose_reason). Write-only; never returned.

Response

Existing document refreshed; indexing rescheduled.

Association between a source and a knowledge base - the only membership model (no files registry). The server computes source_key and dedups on (knowledge_base_id, source_key).

fetch_url is intentionally ABSENT from this schema: it is write-only at the API boundary (may embed credentials). For source_type: uploaded_file no fetch URL is stored at all - storage mints a fresh short-lived one (as a privileged workspace) whenever the crawler needs bytes, so expired-token failures are structurally impossible for uploaded files.

id
string
required
Maximum string length: 128
Pattern: ^vsf_[A-Za-z0-9-]+$
object
enum<string>
required
Available options:
knowledge_base.document
knowledge_base_id
string
required
Pattern: ^vs_[A-Za-z0-9-]+$
source_type
enum<string>
required

Discriminator. uploaded_file for platform-native files (attached by native_file_id); remote_file for document bytes at an arbitrary URL; web_page for HTML pages (single URL or crawl-discovered); connector_document for sources owned by a third-party connector.

Available options:
uploaded_file,
remote_file,
web_page,
connector_document
source_key
string
required
read-only

Server-computed canonical source URI; the dedup key, UNIQUE with knowledge_base_id. prisme-file://{workspace_id}/{native_file_id} for uploaded files (stable across renames - never the rebuilt native URL); web://{normalized_url} otherwise. Normalization is conservative (strip fragment, lowercase scheme + host, normalize percent-encoding, strip default ports - query params untouched) and shared with the crawler's canonicalization.

Maximum string length: 2048
source_url
string<uri>
required

User-facing provenance URL - citations, UI links, audit logs. Stable by construction for connector documents (e.g. SharePoint webUrl) and web pages (the page URL). For uploaded files, a display URL (caller-overridable at attach time); downloadable links are minted lazily via GET /documents/{document_id}/source_url.

origin
enum<string>
required

Provenance, set at row creation and never overwritten by seed adoption. Seed deletion cascades only over origin: web_source rows - a manually attached page later discovered by a seed keeps origin: user and survives the seed's deletion (losing only its web_source_id).

Available options:
user,
web_source
status
enum<string>
required

Authoritative indexing status. Transitions are guarded by index_generation - stale or duplicate callbacks are ignored. fetch_expired is connector-facing: the ephemeral fetch URL no longer works and the owning connector must refresh it via the upsert (POST /documents with the same source_url); it is never a user-actionable error and never occurs for uploaded_file sources. rejected means a before_file_ingest hook blocked the content (an after_file_parse block is failed with last_error.code: HookRejected) - see rejected_by, and public_rejection_reason for the only reason that may be shown to an end user.

Available options:
queued,
in_progress,
completed,
failed,
fetch_expired,
rejected
created_at
integer
required
native_file_id
string | null

Platform-native file id when source_type: uploaded_file.

native_file_workspace_id
string | null

Workspace owning the native file. Defaults to the caller's workspace.

web_source_id
string | null

Primary producing/adopting seed (origin-of-record), when any. Multi-attribution (a page reachable from several seeds) is carried by parent_web_source_ids.

Pattern: ^seed_[A-Za-z0-9-]+$
parent_web_source_ids
string[]
read-only

All seeds whose crawl scope covers this page. Backs per-seed page counts and seed cascade-delete: deleting a seed removes it from this array and drops the row only when the array empties AND origin: web_source. Empty/absent ⇒ unattributed (counted in the /web_sources summary residual).

Pattern: ^seed_[A-Za-z0-9-]+$
crawler_document_id
string | null

Crawler-side document id, set once the crawler has seen this source.

index_generation
integer
read-only

Monotonically increasing per document; incremented on every (re)index. Search reads only the latest committed generation; a reindex swaps the new generation in only on success, so the previous good vectors remain searchable on failure.

Required range: x >= 1
filename
string | null
Maximum string length: 255
mime_type
string | null
bytes
integer | null
Required range: x >= 0
parser
string | null

Parser used at last successful parse.

parsed_at
integer | null
page_count
integer | null
Required range: x >= 0
char_count
integer | null
Required range: x >= 0
chunking_strategy
object | null

Per-document override of the store default.

scope
enum<string>
default:knowledge
Available options:
knowledge,
conversation
conversation_id
string | null
expires_at
integer | null

Unix seconds. TTL for conversation-scope documents.

tags
object

Caller-supplied tags. Editable via PATCH. Filterable on list.

metadata
object

Connector-supplied structured context (e.g. connector, site_id, drive_item_id, version). Editable via PATCH.

chunks_count
integer | null
Required range: x >= 0
vectors_count
integer | null
Required range: x >= 0
last_error
object | null

Most recent failure context. Cleared when a new indexing attempt transitions to in_progress. code: SOURCE_UNAVAILABLE signals a dangling reference (e.g. the native file was deleted out-of-band - native files emit no lifecycle events, so this surfaces at the next fetch).

errors
object[] | null
read-only

Bounded retry/failure history (the most recent failure is also in last_error). For debugging repeated index failures.

message
string | null

Human-readable narrative status, distinct from last_error (e.g. a partial-success or skipped note).

failed_at
integer | null

Unix seconds of the most recent failure.

rejection_reason
string | null

Why an external hook blocked the content, as the hook gave it, kept whether or not the hook config sets expose_reason, so it is for the knowledge base's administrators: never relay it to an end user, and returned only to the base's owners and storage / platform admins (null for any other reader). Set when status: rejected (before_file_ingest) and on a document failed with last_error.code: HookRejected (after_file_parse). With public_rejection_reason and rejected_by, it is the trace of the last refusal: a reindex keeps it and the next failure resets it, so it is meaningful only while the document is rejected or failed with last_error.code: HookRejected.

public_rejection_reason
string | null

The part of rejection_reason the hook allowed to be shown (expose_reason: true); empty otherwise. The only refusal reason a client or an agent may relay to the end user.

rejected_by
string | null

Identifier of the hook that produced the rejection.

indexed_at
integer | null

Unix seconds. Set when the document reaches completed.

updated_at
integer