API: Embeddings
OpenAI-compatible embeddings endpoint of the Kasimir Public API for 1024-dimensional vector embeddings.
The Kasimir Public API embeddings endpoint converts text into numeric vector embeddings that you can use for semantic search, clustering, classification, or your own RAG pipelines. The interface is wire-compatible with the OpenAI Embeddings API: you can use the official OpenAI Python SDK (or any OpenAI-compatible client) unchanged and simply point base_url and api_key at Kasimir. Internally the request is proxied through the GDPR-compliant LiteLLM proxy to the configured embedding model, with tenant governance (model entitlement, EU gate) and per-call usage metering.
Endpoint
Method |
|
URL |
|
Base URL |
|
Content-Type |
|
Auth |
|
Required scope |
|
OpenAI-compatible
In any OpenAI client, set base_url = "https://kasimir.ai/api/v1" and api_key = "<your-kasimir-key>". The request and response shapes mirror OpenAI's POST /v1/embeddings.
Authentication
Every call is authenticated with a company API key passed in the Authorization: Bearer <key> header.
Keys are created by workspace owners or admins under Administration → Access (
/administration/access).The format is
kasi_followed by 32 characters (e.g.kasi_a3f9k2m7q4t6w8x1c5v9b2n4z6s8d0f2). The plaintext is shown only once at creation — afterwards Kasimir stores only a SHA-256 hash.New keys default to the scopes
chat:readandchat:write. Embeddings requirechat:write.Revoked keys (with
revoked_atset) are rejected with401.
Never put the key in client code
Treat the API key like a password. Use it server-side only and never commit it to a repository. If a key leaks, revoke it in /administration/access and create a new one.
Request
Headers
Header | Value | Required |
|---|---|---|
|
| yes |
|
| yes |
Body parameters
Parameter | Type | Required | Description |
|---|---|---|---|
|
| yes | The public model slug of an embedding model, e.g. |
|
| yes | The text to embed. Either a single string or an array of strings for batch embedding. |
Extra fields are passed through
The body is validated with passthrough semantics: additional OpenAI-compatible fields (e.g. encoding_format, dimensions, if the upstream model supports them) are forwarded verbatim to the LiteLLM proxy. Only model and input are mandatory and validated.
Response
The response follows the OpenAI embeddings schema. The model field in the response carries the Kasimir slug (not the internal upstream model ID).
Field | Type | Description |
|---|---|---|
|
| Always |
|
| List of embedding objects (see below). |
|
| The requested Kasimir model slug. |
|
| Token usage: |
Each element in data:
Field | Type | Description |
|---|---|---|
|
| Always |
|
| Position in the |
|
| The vector. For the default model, 1024 dimensions. |
Vector dimension
The configured embedding model self-hosted-bge-m3 (BGE-M3, EU-hosted) returns 1024-dimensional vectors. Kasimir's RAG pipeline is fixed at vector(1024); switching to a model with a different dimension requires a new schema migration.
Examples
curl — single text
curl https://kasimir.ai/api/v1/embeddings \
-H "Authorization: Bearer kasi_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "self-hosted-bge-m3",
"input": "The GDPR governs the handling of personal data."
}'curl — batch (multiple texts)
curl https://kasimir.ai/api/v1/embeddings \
-H "Authorization: Bearer kasi_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "self-hosted-bge-m3",
"input": [
"First paragraph to embed.",
"Second paragraph to embed."
]
}'OpenAI Python SDK
from openai import OpenAI
client = OpenAI(
base_url="https://kasimir.ai/api/v1",
api_key="kasi_YOUR_API_KEY",
)
resp = client.embeddings.create(
model="self-hosted-bge-m3",
input="The GDPR governs the handling of personal data.",
)
vector = resp.data[0].embedding
print(len(vector)) # 1024
print(resp.usage.prompt_tokens)Batch with the Python SDK
texts = [
"First paragraph to embed.",
"Second paragraph to embed.",
]
resp = client.embeddings.create(model="self-hosted-bge-m3", input=texts)
for item in resp.data:
print(item.index, len(item.embedding))Example response
{
"object": "list",
"data": [
{
"object": "embedding",
"index": 0,
"embedding": [0.0123, -0.0456, 0.0789, "...1021 more values..."]
}
],
"model": "self-hosted-bge-m3",
"usage": {
"prompt_tokens": 12,
"total_tokens": 12
}
}Listing models
To discover which slugs are entitled for your workspace, use the models endpoint. It returns both chat and embedding models (filtered by tenant entitlement and the EU gate):
curl https://kasimir.ai/api/v1/models \
-H "Authorization: Bearer kasi_YOUR_API_KEY"client.models.list()Errors
Errors are returned in the OpenAI error format so that standard SDKs handle them normally:
{
"error": {
"message": "Missing scope: chat:write",
"type": "permission_error",
"code": null
}
}The HTTP status code determines the type field:
Status |
| Cause |
|---|---|---|
|
| Invalid body (missing |
|
| No bearer token, invalid key, or revoked key. |
|
| Workspace monthly budget reached. |
|
| Missing scope ( |
|
| Model slug unknown, inactive, or disabled for the workspace. |
|
| Upstream / proxy error (e.g. |
Budget limit (402)
If the workspace has a monthly_budget_eur set and the sum of API and in-app spend for the current calendar month reaches it, every call responds with 402. An unset budget, or one at ≤ 0, means "unlimited".
Governance & billing
Model entitlement: The same rules apply as in the in-app model picker — workspace scope,
active, purposeembedding, thedisabled_model_slugsdeny-list, and the EU/non-EU gate (allow_non_eu_models).EU gate: Non-EU models (
eu_hosted = false) are rejected with403unless the workspace has explicitly enabled them. The default embedding model is EU-hosted.Metering: Every successful call is recorded in the usage ledger (
api_usage) — withprompt_tokensfrom the upstream response and the EUR cost per the model's rates. Metering is best-effort and never blocks the response.
GDPR / data residency
The default embedding slug self-hosted-bge-m3 is marked EU-hosted. If data residency is critical for you, verify via GET /api/v1/models that your chosen model is EU-hosted before embedding personal data.