Skip to content
Numes

Multimodal

Embeddings

Turn text, token arrays, images and PDFs into vectors with POST /embeddings for search, clustering, deduplication and retrieval.

On this page

POST /embeddings follows the OpenAI request and response shapes, so the official SDKs work after you change the base URL and key. Batch up to 2,048 inputs per request, choose float or compact base64 output, and embed images and PDFs with multimodal models.

POST/api/v1/embeddingsReference →

Text inputs preserve JSON-escaped control characters, including terminal escapes. Input and request size limits still apply.

Each input accepts at most 4 MiB of combined text in UTF-8 bytes. A multimodal input accepts up to 128 content parts across text, images, PDFs and audio, subject to media size limits and the selected model's supported inputs.

Create embeddings

curl -X POST "https://api.numes.ai/api/v1/embeddings" \  -H "Authorization: Bearer $NUMES_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "model": "author/embedding-model",    "input": [      "How do I reset my password?",      "Steps to recover a locked account",      "Quarterly revenue grew by 12 percent"    ]  }'

The response holds one vector per input, in input order. Real vectors have hundreds or thousands of dimensions:

Response
{  "id": "embd-3f0c6a5e-9d7b-4c1e-8a2f-6b5d4e3c2a10",  "object": "list",  "model": "author/embedding-model",  "data": [    { "object": "embedding", "index": 0, "embedding": [0.0213, -0.0447, 0.0182, 0.0031] },    { "object": "embedding", "index": 1, "embedding": [0.0198, -0.0402, 0.0211, -0.0007] },    { "object": "embedding", "index": 2, "embedding": [-0.0315, 0.0126, -0.0088, 0.0402] }  ],  "usage": {    "prompt_tokens": 21,    "total_tokens": 21,    "cost": 0.000002  }}

Response body

idstring

embd- followed by the generation ID, which also appears in the X-Generation-Id header.

object"list"

Always list.

modelstring

The canonical model ID that served the request.

dataobject[]

One entry per input item, sorted by index.

Show child attributes
object"embedding"

Always embedding.

indexinteger

Position of the input item, from 0.

embeddingnumber[] | string

The vector: an array of numbers for float, or a base64 string for base64.

usageobject

Usage for the request.

Show child attributes
prompt_tokensinteger

Input tokens for the whole batch.

total_tokensinteger

Equal to prompt_tokens; embeddings produce no output tokens.

costnumber

Total charge in your key's currency.

Request fields

Request body

modelstringRequired

Canonical ID of an embedding model, such as author/embedding-model.

inputstring | string[] | integer[] | integer[][] | ContentPart[][]Required

What to embed. See Input formats.

dimensionsinteger

Length of the returned vectors, from 1 to 65,536, for models that can shorten their output.

encoding_formatstringDefault float

float for arrays of numbers, or base64 for packed little-endian float32 vectors.

input_typestring

Task hint, such as a query or document type. Accepted values depend on the model; at most 128 bytes.

providerobject

Routing preferences, as for chat. See Provider routing.

Other fields, including user, are rejected with 400.

Input formats

input shapeVectors returnedLimits
A string1Non-empty, at most 4 MiB
An array of stringsOne per string1–2,048 strings, each non-empty and at most 4 MiB
An array of token IDs (non-negative integers)1At least one token
An array of token-ID arraysOne per inner array1–2,048 arrays
An array of content-part arraysOne per inner array1–2,048 items

The first element decides how an array is read, so don't mix strings with arrays in one input. Token IDs must come from the model's own tokenizer.

Multimodal inputs

Multimodal embedding models place text, images and documents in one vector space. Each item is an array of content parts, using the same text, image_url, file and input_audio parts as chat, and all parts of one item produce one vector:

curl -X POST "https://api.numes.ai/api/v1/embeddings" \  -H "Authorization: Bearer $NUMES_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "model": "author/multimodal-embedding-model",    "input": [      [        {          "type": "text",          "text": "Red trail running shoe, side view"        },        {          "type": "image_url",          "image_url": {            "url": "https://example.com/images/shoe.jpg"          }        }      ],      [        {          "type": "text",          "text": "Waterproof hiking boot"        }      ]    ]  }'

Wrap a single multimodal item in an outer array as well. Media follows the chat media rules: at most 8 MiB per item and 24 MiB in total. A request with images, PDFs or audio needs an endpoint whose input_modalities include image, file or audio. Video is rejected with 400.

Optional controls and routing

dimensions, input_type and encoding_format: "base64" are forwarded to the selected endpoint. To route only to endpoints that declare every one you set in their supported_parameters, add provider.require_parameters: true; if none does, the request fails with 503 provider_unavailable:

curl -X POST "https://api.numes.ai/api/v1/embeddings" \  -H "Authorization: Bearer $NUMES_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "model": "author/embedding-model",    "input": "How do I reset my password?",    "dimensions": 256,    "input_type": "search_query",    "provider": {      "require_parameters": true    }  }'

encoding_format: "float", or leaving it unset, adds no requirement.

Use the OpenAI SDK

import os​from openai import OpenAI​client = OpenAI(base_url="https://api.numes.ai/api/v1", api_key=os.environ["NUMES_API_KEY"])​response = client.embeddings.create(    model="author/embedding-model",    input=["How do I reset my password?", "Steps to recover a locked account"],    encoding_format="float",)for item in response.data:    print(item.index, len(item.embedding))

Base64 vectors

With encoding_format: "base64", each embedding is a base64 string of little-endian 32-bit floats, considerably smaller than JSON numbers. Decode it like this:

import base64​import numpy as np​def decode_embedding(value: str) -> np.ndarray:    return np.frombuffer(base64.b64decode(value), dtype="<f4")

Find embedding models

curl "https://api.numes.ai/api/v1/models?output_modalities=embeddings" \  -H "Authorization: Bearer $NUMES_API_KEY"

Embedding models have "embeddings": true and embeddings in architecture.output_modalities. To see which endpoints accept image or file input or support dimensions, input_type or encoding_format, read input_modalities and supported_parameters in GET /models/{author}/{slug}/endpoints.

Vectors from different models aren't comparable. Store the model ID with every vector, and re-embed your corpus when you change models. Compare vectors with cosine similarity, or store them in a vector database for nearest-neighbour search.

Batching and limits

LimitValue
Items per request2,048
One string4 MiB
Request body10 MiB
Request timeout10 minutes
Media8 MiB per item, 24 MiB per request
  • Keep each input within the model's context length. The limit applies per input, not to the whole batch.

  • Split very large batches. The funds held before a batch runs grow with the number of items, and its tokens count toward your key's token rate limit, so one huge batch can fail with 402 or 429 where several smaller ones pass. See Limits.

  • Match results by index to map each vector back to its input.

  • Use base64 for large batches to shrink the response.

  • Use a new X-Request-Id for each retry. A reused request ID is rejected with 400.

Billing

Embeddings are billed by input at the endpoint's rates, including any per-request and media prices; there are no output tokens. usage.cost is the exact total in your key's currency, and GET /generation is the authoritative record. See Usage accounting.

Errors

Statuserror_typeCause
400invalid_requestEmpty or malformed input, more than 2,048 items, dimensions outside 1–65,536, unknown encoding_format, video parts, invalid media, unknown field
402insufficient_creditsBalance or key limit can't cover the held amount
408timeoutThe request didn't finish within 10 minutes
413payload_too_largeBody larger than 10 MiB
429rate_limitedKey or account rate limit; wait for Retry-After
503provider_unavailableNo eligible endpoint for the model, its input modalities, required parameters or batch size

Next steps