Embeddings
Text in, vectors out — the same computation ingestion and knowledge search run internally.
Overview
POST /v1/projects/{project_id}/embeddings
embeds one string or a batch of them with the project's configured embedding
model, and returns the raw vectors. There is nothing else in this module.
You do not need it to use knowledge search — that embeds your query for you. It earns its place when you are building an index somewhere else and want the vectors to be comparable with the ones in this project, or when you want to compare two pieces of text directly without storing either.
This module is a verbatim mirror of the runtime: every field, method, status code and error shape is the runtime's own, re-rooted under the project in the path.
See the OpenAPI spec for the full endpoint and schema reference, or browse it rendered under API Reference → Embeddings.
Data Model
Request
| Field | Type | Description |
|---|---|---|
input | string | A single text to embed. |
inputs | array of string | A batch of texts to embed. |
At least one of the two is required.
EmbeddingsResponse
| Field | Type | Description |
|---|---|---|
embedding | array of number | The vector for input. Present when input was sent. |
embeddings | array of array of number | One vector per item in inputs, in order. Present when inputs was sent. |
Key Concepts
Which field you send decides which you get back
input answers embedding; inputs answers embeddings. The response shape
follows the request, so a client that sometimes batches has to read both keys —
or always send inputs, even for one string, and always read embeddings.
Batching is also the cheaper call: one round trip and one provider request for the whole list, rather than one each.
The vectors are the project's, not a global standard
The embedding comes from the model the project's AI provider is configured with, so vectors are only comparable with other vectors produced by the same model. Changing the project's embedding model makes previously stored vectors incomparable with new ones — which is why re-embedding a corpus means re-ingesting it.
Embedding spend is metered
An embedding call's token usage is recorded against the project in the path, so
it reaches that project's
GET /v1/projects/{project_id}/usage
rollup and counts towards its tokens and cost_usd quotas.
Batching changes the round trips, not the total: the meter follows tokens.
Every embedding a project makes — this route, ingestion, memory writes, knowledge
search — is paid from the credit balance, on every plan and whatever provider
you generate with. While the balance is negative, writes that embed answer
402 insufficient_credit; knowledge search does not.
The project is always the one in the path. The endpoint description mentions a
project_id field, which belongs to the runtime's own unrooted route — this API
does not accept one, because the path already names the project.
Who may do what
Embedding needs any project member.
Examples
Embed one string
- CLI
- SDK
- curl
naturali create-embeddings \
--project-id proj_V1StGXR8Z5jdHi6B \
--input "Refunds are issued within 5 business days."
const { data: result } = await naturali.embeddings.createEmbeddings({
path: { project_id: 'proj_V1StGXR8Z5jdHi6B' },
body: { input: 'Refunds are issued within 5 business days.' },
});
console.log(result?.embedding?.length);
curl -X POST https://api.naturali.ai/v1/projects/proj_V1StGXR8Z5jdHi6B/embeddings \
-H "Authorization: Bearer $NATURALI_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "input": "Refunds are issued within 5 business days." }'
Embed a batch
- CLI
- SDK
- curl
naturali create-embeddings \
--project-id proj_V1StGXR8Z5jdHi6B \
--inputs "First paragraph." \
--inputs "Second paragraph."
const { data: result } = await naturali.embeddings.createEmbeddings({
path: { project_id: 'proj_V1StGXR8Z5jdHi6B' },
body: { inputs: ['First paragraph.', 'Second paragraph.'] },
});
console.log(result?.embeddings?.length);
curl -X POST https://api.naturali.ai/v1/projects/proj_V1StGXR8Z5jdHi6B/embeddings \
-H "Authorization: Bearer $NATURALI_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "inputs": ["First paragraph.", "Second paragraph."] }'