API reference
Embeddings API
Base URL https://api.similar.dev/v1. The endpoint follows the OpenAI embeddings wire format, so any client that already speaks that shape works after changing the base URL, API key, and model ID.
Quickstart in your language
Each snippet embeds two documents with the English flagship and reads back 512-dimensional vectors. Replace sme_your_account_... with your key.
from openai import OpenAI client = OpenAI( api_key="sme_your_account_...", base_url="https://api.similar.dev/v1", ) response = client.embeddings.create( model="similar.dev-en-v1-medium-512", input=["First document.", "Second document."], ) vectors = [item.embedding for item in response.data] print(len(vectors[0])) # 512
import OpenAI from "openai"; const client = new OpenAI({ apiKey: "sme_your_account_...", baseURL: "https://api.similar.dev/v1", }); const response = await client.embeddings.create({ model: "similar.dev-en-v1-medium-512", input: ["First document.", "Second document."], }); const vectors = response.data.map((item) => item.embedding); console.log(vectors[0].length); // 512
import OpenAI from "openai"; const client = new OpenAI({ apiKey: process.env.SIMILAR_API_KEY, baseURL: "https://api.similar.dev/v1", }); async function embed(docs: string[]): Promise<number[][]> { const response = await client.embeddings.create({ model: "similar.dev-en-v1-medium-512", input: docs, }); return response.data.map((item) => item.embedding); } const vectors = await embed(["First document.", "Second document."]); console.log(vectors[0].length); // 512
package main import ( "bytes" "encoding/json" "fmt" "net/http" ) func main() { body, _ := json.Marshal(map[string]any{ "model": "similar.dev-en-v1-medium-512", "input": []string{"First document.", "Second document."}, }) req, _ := http.NewRequest("POST", "https://api.similar.dev/v1/embeddings", bytes.NewReader(body)) req.Header.Set("Authorization", "Bearer sme_your_account_...") req.Header.Set("Content-Type", "application/json") resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() var out struct { Data []struct{ Embedding []float32 `json:"embedding"` } `json:"data"` } json.NewDecoder(resp.Body).Decode(&out) fmt.Println(len(out.Data[0].Embedding)) // 512 }
import java.net.URI; import java.net.http.*; public class Embed { public static void main(String[] args) throws Exception { String body = """ {"model": "similar.dev-en-v1-medium-512", "input": ["First document.", "Second document."]} """; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.similar.dev/v1/embeddings")) .header("Authorization", "Bearer sme_your_account_...") .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(body)) .build(); HttpResponse<String> response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); // data[i].embedding has 512 floats } }
use serde_json::{json, Value}; #[tokio::main] async fn main() -> Result<(), reqwest::Error> { let client = reqwest::Client::new(); let response: Value = client .post("https://api.similar.dev/v1/embeddings") .bearer_auth("sme_your_account_...") .json(&json!({ "model": "similar.dev-en-v1-medium-512", "input": ["First document.", "Second document."] })) .send().await? .json().await?; let dims = response["data"][0]["embedding"].as_array().unwrap().len(); println!("{dims}"); // 512 Ok(()) }
using System.Net.Http.Headers; using System.Net.Http.Json; using System.Text.Json; var http = new HttpClient(); http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "sme_your_account_..."); var response = await http.PostAsJsonAsync( "https://api.similar.dev/v1/embeddings", new { model = "similar.dev-en-v1-medium-512", input = new[] { "First document.", "Second document." } }); using var doc = JsonDocument.Parse(await response.Content.ReadAsStringAsync()); var dims = doc.RootElement.GetProperty("data")[0].GetProperty("embedding").GetArrayLength(); Console.WriteLine(dims); // 512
curl https://api.similar.dev/v1/embeddings \ -H "Authorization: Bearer sme_your_account_..." \ -H "Content-Type: application/json" \ -d '{ "model": "similar.dev-en-v1-medium-512", "input": ["First document.", "Second document."] }' # response.data[0].embedding -> 512 float32 values
Authentication
Send your key as Authorization: Bearer sme_.... The API also accepts X-API-Key and, for quick tests, ?api_key=. Keys are minted after the initial credit deposit on the Developer plan.
POST /v1/embeddings
| Field | Type | Notes |
|---|---|---|
model | string | Any published model ID. See the catalog below. |
input | string or string[] | Up to 100 documents per request. |
input_type | string, optional | Defaults to document. |
dims | integer, optional | Clip output below 512 with renormalization. Omit for the full 512. |
Response: {"object": "list", "data": [{"object": "embedding", "index": 0, "embedding": [...]}], "model": "...", "usage": {"prompt_tokens": n, "total_tokens": n}}.
Model IDs
| ID | Locale | Best for |
|---|---|---|
similar.dev-en-v1-medium-512 | en-US | English flagship. Retrieval, clustering, semantic search. |
similar.dev-en-v1-lite-512 | en-US | High-volume English pipelines where cost dominates. |
similar.dev-lang3-lite-512 | en-US, es-419, pt-BR | Cross-language document similarity in one space. |
GET /v1/models
Authenticated clients receive every model ID available to the account. Select models by ID in code rather than assuming the current default is the whole catalog.
Similarity
Compare vectors with cosine similarity. Outputs are float32 and not guaranteed to have unit L2 length; normalize inside your index if it requires unit vectors.
Limits
- Maximum 100 inputs per request.
- Current models are document-mode embeddings, tuned for symmetric similarity rather than asymmetric query-document retrieval.
- Telemetry records counts, timing, and status codes. Customer text is never logged.
Model lifecycle
Every published model ID remains callable for a minimum of five years from launch before any retirement notice. Language-specific endpoints and custom-fit models will carry the same commitment when released.