Skip to content

Embeddings

POST /v1/embeddings turns clinical text into embedding vectors with ClinEmbed-1. It follows the OpenAI embeddings API shape plus one field, input_type, so the openai SDKs work when you point their base URL at the gateway. For the base URLs and the headers every response carries, see API overview.

POST /v1/embeddings
Authorization: Bearer fh_...
Content-Type: application/json

The request takes the following headers:

Header Required Description
Authorization Yes Bearer followed by your API key.
Content-Type Yes application/json.
x-request-id No Your own ID for the request. The gateway returns it in the x-request-id response header; without it, the gateway generates a UUID.

The body is a JSON object with the following fields:

Field Type Required Description
model string Yes The model ID. ClinEmbed-1 is the only model served. A request for a model your organization doesn’t have access to returns 403 model_not_enabled.
input string or array of strings Yes The text to embed. An array holds 1 to 1,000 strings and returns one embedding per string, in the same order. Each string can have at most 512 tokens; see Long inputs.
input_type string No query or document. Tells the model which side of a retrieval pair the text is on; see Input types.
encoding_format string No float (default) or base64. See Encoding formats.
truncate_prompt_tokens integer No Set to -1 to truncate inputs longer than 512 tokens instead of rejecting them. See Long inputs.
dimensions integer No Not supported. ClinEmbed-1 always returns 1024 dimensions; a request that sets dimensions fails with 400 invalid_request.
user string No Accepted and forwarded for compatibility with the OpenAI embeddings API.

The body must be at most 1 MiB. The gateway drops fields that aren’t listed here before the request reaches the model.

ClinEmbed-1 embeds search queries differently from documents, so that a query’s vector is close to the vectors of the documents that answer it. input_type tells the model which one a text is:

  • query: a search string. The model prepends its retrieval instruction to the text before embedding it, so the vector differs from the one you get without an input_type.
  • document: text that you index for retrieval. This produces the same vector as omitting input_type.

For retrieval and semantic search, embed your corpus with document and every search string with query, and then rank documents by similarity to the query vector. For tasks where all texts play the same role, such as clustering or deduplicating notes, embed them all the same way: with document or with no input_type.

The gateway rejects any other value with 400 invalid_body.

ClinEmbed-1 accepts up to 512 tokens per input string. The count includes the instruction that input_type: "query" adds. By default, one input over the limit fails the whole request with 400 invalid_request and a detail that mentions the maximum context length. To embed the first 512 tokens of each over-long input instead, set truncate_prompt_tokens to -1. The response’s usage then counts only the tokens the model embedded.

encoding_format selects how the response encodes each vector:

  • float (default): embedding is a JSON array of 1024 numbers.
  • base64: embedding is a base64 string of the 1024 values as little-endian 32-bit floats, which makes the response smaller. Decode it with struct.unpack("<1024f", base64.b64decode(value)) in Python, or decode the base64 into bytes and read them as a Float32Array in JavaScript.

The openai SDKs request base64 when you don’t set encoding_format and decode it for you, so embedding is an array of numbers in your code either way.

A success is 200 with Content-Type: application/json; charset=utf-8 and the following fields:

Field Type Description
id string An ID for the response.
object string Always list.
created integer When the response was created, as a Unix timestamp in seconds, as in the OpenAI API.
model string The model that produced the embeddings: ClinEmbed-1.
data array One item per input string, in input order.
data[].object string Always embedding.
data[].index integer The position of the input this embedding belongs to, starting at 0.
data[].embedding array of numbers, or string The 1024-dimensional vector, as numbers or as a base64 string depending on encoding_format. Vectors are unit length, so the dot product of two embeddings is their cosine similarity.
usage.prompt_tokens integer Tokens in the inputs, including the instruction that input_type: "query" adds.
usage.total_tokens integer Same as prompt_tokens. The gateway records this number as your usage for the request.

The following example shows a response for two inputs:

200 OK
{
"id": "embd-3f9c2a7e",
"object": "list",
"created": 1758643200,
"model": "ClinEmbed-1",
"data": [
{ "object": "embedding", "index": 0, "embedding": [0.0123, -0.0456, 0.0078 /* 1024 values */] },
{ "object": "embedding", "index": 1, "embedding": [-0.0311, 0.0197, 0.0402 /* 1024 values */] }
],
"usage": { "prompt_tokens": 48, "total_tokens": 48 }
}

The examples embed two clinical notes as documents, and then embed a search string as a query and rank the notes against it. Vectors are unit length, so ranking by dot product ranks by cosine similarity. The SDK examples set the base URL with a /v1 suffix and pass the Fourier API key as the API key. Because input_type isn’t in the SDK types, the Python example passes it through extra_body, and the TypeScript example widens the parameter type.

curl https://gateway.fourierhealth.com/v1/embeddings \
-H "Authorization: Bearer $FOURIER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "ClinEmbed-1",
"input": [
"Hemoglobin A1c 7.9% (ref 4.0-5.6) collected 03/14/2024.",
"Allergies: penicillin (rash), sulfa drugs. No known food allergies."
],
"input_type": "document"
}'

This example continues from the previous one. The HbA1c note scores highest.

curl https://gateway.fourierhealth.com/v1/embeddings \
-H "Authorization: Bearer $FOURIER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "ClinEmbed-1",
"input": "most recent HbA1c result",
"input_type": "query"
}'

Besides the authentication, rate limit, and availability errors every endpoint can return, this endpoint returns the following:

Status Code When
400 invalid_body The body fails validation: model missing, input empty or over 1,000 strings, or an unknown input_type or encoding_format. detail names the field.
400 invalid_request The model rejected the request: an input over 512 tokens without truncate_prompt_tokens, or a dimensions value. detail carries the model’s message.
403 model_not_enabled Your organization doesn’t have access to the requested model, or no such model exists. Contact Fourier Health to request access.

For the response format and the full list of codes, see Errors.