Skip to content

Embeddings

Show:

Schift provides a unified embedding API that proxies to multiple providers (OpenAI, Google, Voyage, Cloudflare, HuggingFace, and more) through a single set of endpoints. All embeddings pass through Schift’s Canonical Projection layer, so you can switch models or reduce dimensions without re-embedding your data.

All embedding endpoints require a Bearer token in the Authorization header:

Authorization: Bearer sch_xxxxxxxxxxxxxxxxxxxx

API keys are managed in the Schift dashboard under Settings > API Keys.

ModelProviderDefault dimensionMax tokensVariable dimensions
schift-embed-1-smallSchift (auto)10248,192Yes
openai/text-embedding-3-smallOpenAI15368,191Yes
openai/text-embedding-3-largeOpenAI30728,191Yes
google/gemini-embedding-001Google30728,191Yes
google/gemini-embedding-002Google30728,191Yes
voyage/voyage-4-largeVoyage AI102432,000Yes
voyage/voyage-4Voyage AI102432,000Yes
voyage/voyage-4-liteVoyage AI102432,000Yes
dragonkue/bge-m3-koHuggingFace10248,192No
jinaai/jina-embeddings-v3HuggingFace10248,194Yes
sbintuitions/sarashina-embedding-v2-1bHuggingFace17928,192No

schift-embed-1-small is an auto-routed alias. Schift selects the best underlying model based on the input language and passes the result through the canonical projection layer. The resolved model is returned in the model field of every response.

Note: Internal backend aliases such as @cf/qwen/qwen3-embedding-0.6b may be returned as the resolved model when schift-embed-1-small is used.

Embedding endpoints optionally accept a task_type that tells Schift how the embedding will be used. The value is passed through to instruct-aware models or converted into an internal prefix for prefix-style models.

task_typeUse case
retrieval_querySearch query embedding
retrieval_documentDocument embedding
semantic_similaritySemantic similarity comparison
question_answeringQuestion-answering retrieval
clusteringClustering or topic grouping
classificationClassification
code_retrievalCode search
contradictionContradiction or counter-evidence search
factcheckFact-checking evidence search

Embed a single text string.

ParameterTypeRequiredDefaultDescription
textstringYesThe text to embed.
modelstringNoOrg routing configModel ID from the catalog.
dimensionsintegerNoModel defaultOutput dimension. Only supported by models with variable dimensions.
task_typestringNoEmbedding intent. See Task types.
FieldTypeDescription
embeddingnumber[]The embedding vector.
modelstringThe model that was actually used.
dimensionsintegerThe output dimension of the embedding.
usage.tokensintegerNumber of tokens consumed.
Terminal window
curl https://api.schift.io/v1/embed \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SCHIFT_API_KEY" \
-d '{
"text": "Schift enables seamless embedding model migration without re-embedding your data.",
"model": "openai/text-embedding-3-large"
}'
{
"embedding": [-0.01225, 0.00207, 0.03060],
"model": "openai/text-embedding-3-large",
"dimensions": 3072,
"usage": {"tokens": 14}
}

Synchronous batch embedding. Processes up to 100 texts in a single request. For larger inputs, use POST /v1/embed/jobs.

ParameterTypeRequiredDefaultDescription
textsstring[]YesList of texts to embed (max 100).
modelstringNoOrg routing configModel ID from the catalog.
dimensionsintegerNoModel defaultOutput dimension.
task_typestringNoEmbedding intent.
FieldTypeDescription
embeddingsnumber[][]List of embedding vectors, one per input text.
modelstringThe model that was used.
dimensionsintegerThe output dimension.
usage.tokensintegerTotal tokens across all texts.
usage.countintegerNumber of texts embedded.
Terminal window
curl https://api.schift.io/v1/embed/batch \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SCHIFT_API_KEY" \
-d '{
"texts": [
"The Mediterranean diet emphasizes fish, olive oil, and vegetables.",
"Photosynthesis converts light energy into chemical energy.",
"Shakespeare wrote Hamlet and A Midsummer Night'"'"'s Dream."
],
"model": "voyage/voyage-4-large"
}'
{
"embeddings": [
[-0.01225, 0.00207, 0.03060],
[0.00898, -0.00298, 0.01546],
[-0.06297, -0.04777, -0.10113]
],
"model": "voyage/voyage-4-large",
"dimensions": 1024,
"usage": {"tokens": 38, "count": 3}
}

Create an asynchronous bulk embedding job. Use this endpoint for 101 to 10,000 texts.

ParameterTypeRequiredDefaultDescription
textsstring[]YesList of texts to embed (max 10,000).
modelstringNoOrg routing configModel ID from the catalog.
dimensionsintegerNoModel defaultOutput dimension.
task_typestringNoEmbedding intent.
FieldTypeDescription
idstringBulk embed job ID.
statusstringInitial status (queued).
modelstringModel selected for the job.
usage.tokensintegerTotal validated tokens across all texts.
usage.countintegerNumber of texts submitted.
chunk_sizeintegerWorker chunk size (currently 100).
Terminal window
curl https://api.schift.io/v1/embed/jobs \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SCHIFT_API_KEY" \
-d '{
"texts": ["doc 1", "doc 2", "doc 3"],
"model": "schift-embed-1-small",
"task_type": "retrieval_document"
}'
{
"id": "job_123",
"status": "queued",
"model": "schift-embed-1-small",
"usage": {"tokens": 6, "count": 3},
"chunk_size": 100
}

Retrieve the status and metadata of a bulk embed job.

ParameterTypeDescription
job_idstringThe bulk embed job ID.
StatusMeaning
queuedJob created and waiting for a worker.
embeddingWorker is embedding text chunks.
indexingResults are being prepared and stored.
readyResults are available for retrieval.
failedJob failed.
cancelledJob was cancelled before processing.
Terminal window
curl https://api.schift.io/v1/embed/jobs/job_123 \
-H "Authorization: Bearer $SCHIFT_API_KEY"
{
"id": "job_123",
"status": "ready",
"org_id": "org_abc",
"metadata": {
"mode": "embed_bulk",
"model": "schift-embed-1-small",
"dimensions": null,
"task_type": "retrieval_document",
"input_count": 3,
"chunk_size": 100,
"token_count": 6,
"completed_count": 3
}
}

Cancel a queued bulk embed job. Only jobs in queued status can be cancelled.

ParameterTypeDescription
job_idstringThe bulk embed job ID.
Terminal window
curl -X POST https://api.schift.io/v1/embed/jobs/job_123/cancel \
-H "Authorization: Bearer $SCHIFT_API_KEY"
{
"status": "cancelled"
}

Retrieve the paginated results of a completed bulk embed job.

ParameterTypeDescription
job_idstringThe bulk embed job ID.
ParameterTypeDefaultDescription
offsetinteger0Number of results to skip.
limitinteger100Maximum number of results to return (max 1,000).
FieldTypeDescription
objectstringAlways list.
dataobject[]Paginated embedding result items.
modelstringModel used for the result.
dimensionsintegerOutput dimension.
usage.countintegerTotal embedded item count.
pagination.offsetintegerRequested offset.
pagination.limitintegerRequested limit.
pagination.returnedintegerNumber of items returned in this page.
pagination.totalintegerTotal result item count.
pagination.has_morebooleanWhether more pages remain.
Terminal window
curl "https://api.schift.io/v1/embed/jobs/job_123/result?offset=0&limit=100" \
-H "Authorization: Bearer $SCHIFT_API_KEY"
{
"object": "list",
"data": [
{"object": "embedding", "index": 0, "embedding": [-0.01225, 0.00207]},
{"object": "embedding", "index": 1, "embedding": [0.00898, -0.00298]},
{"object": "embedding", "index": 2, "embedding": [-0.06297, -0.04777]}
],
"model": "schift-embed-1-small",
"dimensions": 1024,
"usage": {"count": 3},
"pagination": {
"offset": 0,
"limit": 100,
"returned": 3,
"total": 3,
"has_more": false
}
}

Embed images by first extracting text with a vision-language model, then embedding the extracted text. Accepts up to 20 base64-encoded images per request.

ParameterTypeRequiredDefaultDescription
imagesstring[]YesBase64-encoded image data.
modelstringNoOrg routing configModel ID from the catalog.
dimensionsintegerNoModel defaultOutput dimension.
FieldTypeDescription
embeddingsnumber[][]List of embedding vectors, one per image.
modelstringThe model that was used.
dimensionsintegerThe output dimension.
usage.image_countintegerNumber of images processed.
usage.tokensintegerTotal tokens consumed.
Terminal window
curl https://api.schift.io/v1/embed/image \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SCHIFT_API_KEY" \
-d '{
"images": ["iVBORw0KGgoAAAANSUhEUg..."],
"model": "openai/text-embedding-3-large"
}'
{
"embeddings": [[-0.01225, 0.00207, 0.03060]],
"model": "openai/text-embedding-3-large",
"dimensions": 3072,
"usage": {"image_count": 1, "tokens": 14}
}

OpenAI-compatible embeddings endpoint. Accepts the same input shape as OpenAI’s /v1/embeddings and returns an OpenAI-compatible response shape. This endpoint is a thin wrapper over the same logic as /v1/embed and /v1/embed/batch.

Note: For more than 100 inputs, use POST /v1/embed/jobs instead.

ParameterTypeRequiredDefaultDescription
inputstring | string[]YesText or list of texts to embed.
modelstringNoOrg routing configModel ID from the catalog.
dimensionsintegerNoModel defaultOutput dimension.
task_typestringNoSchift extension: embedding intent.
encoding_formatstringNoAccepted for compatibility, currently unused.
userstringNoAccepted for compatibility, currently unused.
FieldTypeDescription
objectstringAlways list.
dataobject[]Embedding objects with object, index, and embedding.
modelstringThe model that was used.
usage.prompt_tokensintegerTotal tokens consumed.
usage.total_tokensintegerTotal tokens consumed.
Terminal window
curl https://api.schift.io/v1/embeddings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SCHIFT_API_KEY" \
-d '{
"input": "Schift enables seamless embedding model migration.",
"model": "openai/text-embedding-3-large"
}'
{
"object": "list",
"data": [
{
"object": "embedding",
"index": 0,
"embedding": [-0.01225, 0.00207, 0.03060]
}
],
"model": "openai/text-embedding-3-large",
"usage": {
"prompt_tokens": 8,
"total_tokens": 8
}
}

Every embedding returned by Schift is projected into a shared canonical latent space. This enables:

  • Model switching without re-embedding. Move from OpenAI to Voyage without touching your vector store.
  • Cross-model search. Query vectors from one model can retrieve documents embedded with another.
  • Dimension reduction. Request any output dimension regardless of the source model’s native dimension.

The projection happens transparently. Call the API normally and Schift handles the rest.

Your organization can configure a default embedding model and optional fallback. When failover mode is enabled, Schift automatically retries with the fallback model if the primary provider is unavailable.

Use the routing endpoints to configure defaults:

Terminal window
curl -X PUT https://api.schift.io/v1/routing \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SCHIFT_API_KEY" \
-d '{
"primary": "openai/text-embedding-3-large",
"fallback": "voyage/voyage-4-large",
"mode": "fallback"
}'

The response from every embed endpoint includes the model field so you always know which model was used.

Rate limits are enforced per organization. Usage is tracked in real time. The following axes are checked for embedding endpoints:

EndpointQuota axis
POST /v1/embedembed
POST /v1/embed/batchembed_batch
POST /v1/embed/imageembed_image
POST /v1/embed/jobsembed_batch
POST /v1/embeddingsembed or embed_batch

Retrieve current usage with:

Terminal window
curl https://api.schift.io/v1/usage/summary \
-H "Authorization: Bearer $SCHIFT_API_KEY"

Bulk embed jobs are assigned a priority based on your organization’s plan:

PlanPriority
Enterprise0
Business1
Pro / Paid / Starter2
Free3

Lower numbers are processed first.

StatusMeaning
400Bad request — unknown model, invalid dimensions, empty input, or token limit exceeded.
401Invalid or expired API key.
402Insufficient credits or quota exceeded.
403Feature not available on your plan or entitlement limit reached.
502Upstream embedding provider failed (both primary and fallback).
EndpointStatusMeaning
POST /v1/embed/batch400More than 100 texts in a sync request. Use POST /v1/embed/jobs.
POST /v1/embed/jobs400Empty texts, more than 10,000 texts, or a text exceeds the model’s max_tokens.
GET /v1/embed/jobs/\{job_id\}404Job not found or belongs to another organization.
POST /v1/embed/jobs/\{job_id\}/cancel400Job is already processing or completed.
POST /v1/embed/jobs/\{job_id\}/cancel409Job is no longer queued.
GET /v1/embed/jobs/\{job_id\}/result404Job or result not found.
GET /v1/embed/jobs/\{job_id\}/result409Result not ready yet.