read:source:raw distinction is not a universal field-redaction guarantee.
Classify sensitive source locations in the record security envelope. See
security.
Versioned source ingestion
For application synchronization, use the named-space source lifecycle. It binds an external identity to immutable text revisions, opaque generations and durable operation receipts. Source writes requireread:source and write:source; reads
require read:source. Select the space in the path or X-Space-Id as applicable.
See service setup for credentials, grants and
processing approvals.
media_type is text/plain or text/markdown. Percent-encode each path component
once. Metadata keys prefixed by _ are reserved. Changing immutable text,
labels or security metadata requires a new revision.
HTTP 202 is durable acceptance, not completion. Poll operation_id from that
response with X-Space-Id: research, then read the current head. Operation states
are pending, running, complete, failed_retryable and failed_final.
Completed historical operations do not guarantee that their revision remains
current after replacement or withdrawal. A reused revision with different
immutable payload conflicts. Identical idempotent replay returns the original
operation; on conflict_generation, reconcile the head before replacement.
Retraction and erasure take {"expected_generation":"generation-from-head"}.
They require an explicit operation; an ordinary retry must not undo them.
Reactivation uses reactivate:true on PUT; recreation after erasure uses
recreate_after_erasure:true. Both require the current tombstone generation.
Physical erasure removes source-derived payload and retains an independent
payload-free recovery journal; registered backups obey bounded retention.
MCP provides get_source_head, get_source_operation, retract_source and
erase_source using the same selected-space and generation contract. Inspect
tools/list for their exact arguments. The inventory endpoint is bounded
reconciliation, not a snapshot or lossless change feed. Retain external-to-internal
identity mappings at admission; erased identifiers cannot be recovered from it.
Retained source-record endpoints
These older ingestion and record APIs remain available with their own contracts. Use the versioned lifecycle above when synchronizing application revisions.Endpoints
Ingest a source
Use the normalized ingest endpoint to generate base fields, stage supplied content, and enqueue source-first processing:name is required. Optional inputs include uri, source_type, title, text,
media, collection, metadata, rendition_key, extraction_skill, extraction_purpose, extraction_domain,
ingest_mode, and sync. Supported source types are email, calendar, web,
drive, chat, device_frame, device_video, transcript, and manual.
A request with staged document content defaults to graph mode; a source without
it defaults to metadata. Other ingest modes are skip and retrieval. A URI
is provenance metadata, not a promise that this endpoint will fetch and render
arbitrary web content. Supply content for retrieval/graph ingestion.
The response contains source_id, lifecycle_status, current_ingest_mode,
work_item_id, and optional doc_id. Follow work and runtime status as described
in System. See Documents for media inputs.
Raw source record format
POST /v1/sources creates a record without scheduling the source-first workflow.
It accepts the complete Source type, including flattened base fields:
source.json
type, not the ingest endpoint’s source_type. Use fresh IDs,
actual timestamps and content hashes, the correct space, and your policy’s labels.
Additional fields include path, parent, range, timestamp, author,
channel, metadata, and lifecycle information.
Search and lifecycle
query, include_deleted (default false), limit (default 50),
and cursor. It returns full source records under results, plus cursor,
has_more, and total, filtered by the caller’s authorization.
GET by ID returns the full source and accepts include_deleted=true. To update,
read the record, modify its intended fields, and send the complete JSON to
PUT /v1/sources/{id}. Keep the ID consistent with the path. This is replacement,
not a partial patch. DELETE soft deletes and returns 204; POST to the
/restore route restores and returns the record.