Docs

Core Concepts

Schift separates the default Schift Embed 1 path from migration-first vector conversion so each surface stays explicit.

Embedding vectors from different models are not natively compatible. Even when dimensions match, the geometry changes with the model.

Two product surfaces

SurfacePrimary objectsUse it for
Schift Embed 1 default pathSchift, catalog, embed, db, query, usageNew embedding calls, hosted collections, and canonical-space retrieval
Migration-first runtimeClient, Projection, migrate(), adaptersLearning a projection matrix and rewriting stored vectors without raw text

Projection matrix

textsource vectors (N, src_dim)
        -> learned matrix W (src_dim, tgt_dim)
        -> projected vectors (N, tgt_dim)

Schift learns W from paired examples embedded by both models. At runtime, migration is just a matrix multiply on the existing vectors.

Adapter pipeline

textAdapter(source store)
        -> Projection.transform(batch.embeddings)
        -> Adapter(sink store)
PropertyTypical range
Paired samples needed500-2,000
Supported migration shapes1536->768, 3072->1024, and more
Runtime costSub-millisecond per vector
Bulk raw text requiredNo

Temporal Constraints

Every vector can carry an event_time metadata field (epoch milliseconds). The temporal query parameter filters results by time, enabling point-in-time retrieval and time-series search.

ModeBehaviorRequired Fields
beforeevent_time < temporal_starttemporal_start
afterevent_time > temporal_starttemporal_start
betweentemporal_start <= event_time <= temporal_endtemporal_start, temporal_end
as_ofevent_time <= temporal_start (snapshot at a point in time)temporal_start
latestSort by most recent event_timeNone

Vectors without an event_time field are excluded from all temporal queries. The latest mode over-fetches candidates by 20x before sorting to ensure quality results.

pythonfrom schift import Schift

client = Schift(api_key="sch_xxx")

# Documents from the last 24 hours
import time
one_day_ago = int((time.time() - 86400) * 1000)
results = client.collections.search(
    "news", "latest AI developments",
    temporal="after", temporal_start=one_day_ago,
)

# Snapshot: what was indexed as of Jan 1, 2026
results = client.collections.search(
    "contracts", "termination clause",
    temporal="as_of", temporal_start=1735689600000,
)

Edges & Graph

Schift can use document relationships as part of the server-side retrieval pipeline. New integrations should consume the v2 knowledge search result instead of managing graph edges directly.

RelationUse Case
related_toGeneral association (default)
supersedesNewer version replaces older document
contradictsTwo documents conflict
caused_byCausal chain between events or issues
is_aTaxonomy / classification hierarchy
has_childParent-child tree structure
followsSequential ordering (e.g., legal articles)

Relationship expansion is treated as an internal retrieval concern for new products. The client receives packed context, citations, and warnings from one search call.

bash# Ask through the v2 knowledge-search pipeline
curl -X POST https://api.schift.io/v2/buckets/{bucket_id}/search \
  -H "Authorization: Bearer $SCHIFT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "Which article supersedes article 42?", "top_k": 8}'