Why it matters How it works Pricing Quickstart Privacy Get started →
idemapi logo
Fuzzy extractor logic for embeddings.

From similarity to certainty.

Stable, deterministic IDs from noisy embeddings. Think fuzzy extractors, but for complex, non-binary embeddings.

Face login Voice auth Document provenance Fraud and risk Device trust Any embedding model

The product flow is simple.

Four steps. Two API calls. One equality check in your application.

01
IN

You send an embedding

Keep your current model. IdemAPI starts where your encoder output begins.

02
BN

We return anchor + ID

POST /v1/bind gives you stable material for future use. Nothing is stored server-side.

03
DB

You store them

Save the anchor and id in your own database, object store or keychain.

04
ID

You derive the ID later

POST /v1/derive with a fresh embedding plus the anchor. The server returns a derived ID. Your app compares it to the stored one.

The applications are broad. These are only a few concrete ones.

Once you can turn noisy embeddings into stable IDs, the pattern applies far beyond one product category. Here are three examples, shown end to end.

Real example

Face verification, shown as API calls and stored JSON.

This is only an example. The same bind-then-derive flow applies to any embedding generated by any model.

1
First face sample

User signs in for the first time

Your face model outputs an embedding. You send it to /v1/bind.

Request
POST /v1/bind
{
  "embedding": [0.14, -0.82, 0.33, 0.91, -0.27, 0.45, ...],
  "strictness": 0.55
}
Response
{
  "anchor": "0006a3f9...",
  "id": "f29c6ab1...",
  "dim": 512,
  "strictness": 0.55
}
2
Your storage

You persist only what you need

You store the returned material next to the user record. No raw embedding needs to live in your backend.

Your database row
{
  "user_id": "user_42",
  "anchor": "0006a3f9...",
  "id": "f29c6ab1..."
}
3
Later login attempt

You derive from a fresh observation

The user comes back, your model emits a new embedding, and you call /v1/derive with that embedding plus the stored anchor.

Request
POST /v1/derive
{
  "embedding": [0.11, -0.80, 0.31, 0.89, -0.24, 0.48, ...],
  "anchor": "0006a3f9..."
}
Response
{
  "id": "f29c6ab1..."
}
4
Your application logic

You do one exact comparison

Your backend compares the returned ID with the stored ID. Equal means same source. Different means reject.

Application check
stored_id  = "f29c6ab1..."
derived_id = "f29c6ab1..."

accepted = (stored_id == derived_id)
Another example

Evaluate the real-world precision of one embedding model.

Run one model over a labeled dataset, sweep strictness, and measure the actual match behavior you get in production terms.

1
Labeled dataset

Start with a known pair

Take two samples whose ground truth you already know, for example same person or different person, and embed them with the model you want to evaluate.

Request
POST /v1/bind
{
  "embedding": [0.23, -0.61, 0.08, 0.74, ...],
  "strictness": 0.55
}
Response
{
  "anchor": "0091bc4d...",
  "id": "8a14d02f...",
  "dim": 768,
  "strictness": 0.55
}
2
Model outcome

Check whether the pair matches

Bind the first sample, derive from the second, and compare IDs. Repeat that process across positive and negative pairs to see how the model really behaves.

Request
POST /v1/derive
{
  "embedding": [0.19, -0.59, 0.11, 0.71, ...],
  "anchor": "0091bc4d..."
}
Response
{
  "id": "8a14d02f..."
}
3
Your application logic

You compute precision metrics for that model

Each pair gives you a ground-truth label and an exact-match result. Sweep strictness: if the model keeps good precision at higher values, the embeddings are strong; if accuracy falls apart early, the model is weak for that task.

Evaluation summary
{
  "model": "face_encoder_v1",
  "strictness": 0.55,
  "pairs_evaluated": 10000,
  "precision": 0.972,
  "false_accept_rate": 0.004,
  "false_reject_rate": 0.024
}
Another example

User-profile deduplication, even when the text is not identical.

Use text embeddings from forms, bios or profile fields to decide when two slightly different records still describe the same person.

1
First profile

Bind one version of the user profile

You embed the first form or profile record, then bind it once to get a stable anchor and ID for that entity.

Profile text before embedding
{
  "name": "John Doe",
  "title": "Product Manager",
  "company": "Acme",
  "city": "New York"
}
Request
POST /v1/bind
{
  "embedding": [0.07, -0.42, 0.58, 0.11, ...],
  "strictness": 0.55
}
Response
{
  "anchor": "00af92bd...",
  "id": "7be31fd0...",
  "dim": 768,
  "strictness": 0.55
}
2
Similar record

Derive from a slightly different version

A second record may not be textually identical, but if it describes the same person, the derived ID can still match.

Profile text before embedding
{
  "name": "John A. Doe",
  "title": "Product Lead",
  "company": "Acme Inc.",
  "city": "New York, NY"
}
Request
POST /v1/derive
{
  "embedding": [0.05, -0.39, 0.60, 0.13, ...],
  "anchor": "00af92bd..."
}
Response
{
  "id": "7be31fd0..."
}
3
Your application logic

You resolve whether both records are the same entity

If the IDs match, your application can treat both records as the same underlying entity even when the raw text differs slightly.

Resolution result
{
  "record_a": "crm_1021",
  "record_b": "lead_8874",
  "strictness": 0.55,
  "same_entity": true,
  "action": "merge"
}

One dial. Three very different operating modes.

strictness is the parameter you send to the API to decide how selective matching should be. The default is 0.5, which is usually the right starting point for production.

Interactive explainer

Default to 0.5 unless you have hard evidence to move away from it.

Current strictness
0.5
Lenient Balanced Exact
Sweet Spot 0.5 is the default operating point.

Enough tolerance for noisy embeddings. Enough selectivity to keep different sources apart.

False accept risk: balanced False reject risk: balanced
Low strictness 0.00โ€“0.34

Too permissive for most production auth.

Good if you deliberately want broad grouping, risky if you need identity-grade separation.

High strictness 0.66โ€“1.00

Very selective and easy to overtune.

Useful only if your encoder is exceptionally stable and you have evidence that aggressive selectivity improves outcomes.

Embeddings are probabilistic. Applications often need determinism.

The exact same source will not emit the exact same vector every time, so perfect determinism is not free. If you always sent the exact same embedding, you would not need this product in the first place.

What teams usually want is a simpler operating model.

Instead of score thresholds, nearest-neighbor infrastructure and repeated comparison logic, IdemAPI gives you a deterministic ID flow. The strictness parameter controls how precisely embeddings must match: lower values accept more variation, higher values demand near-exact similarity.

Simple pricing for stateless compute.

One operation = one bind or one derive call. No storage fees, no seat pricing, no database markup.

Backend-aware model

Bind and derive run on the same stateless Railway-backed request path and show similar latency in current tests, so pricing them per operation is the cleanest model for both product clarity and margin.

Developer
$0/mo
Eval
2,500 operations / month
Enough to wire the API in, test strictness, and run small internal demos.
  • 1 operation = 1 bind or derive
  • Basic rate limits
  • Community support
Growth
$199/mo
Volume-efficient
600,000 operations / month
For production workloads where lower blended cost per call starts to matter.
  • $0.45 per extra 1,000 operations
  • Priority support
  • Higher default rate limits
Scale
Custom
3M+ ops
Volume contract
For larger platforms that want custom limits, direct auth, and enterprise commercial terms.
  • Volume discounts
  • Bearer auth option
  • SLA and invoicing
Why this model works: your hot path is stateless compute, not storage-heavy infrastructure. That lets you stay generous on entry pricing and still make money on production volume.

Two REST calls.

Base URL: https://api.idem.algoritful.com  ·  Direct access uses Authorization: Bearer <api_key>. If you expose the API through RapidAPI instead, use X-RapidAPI-Proxy-Secret and X-RapidAPI-User.

1

Bind

Send one embedding. Store the returned anchor and id.

bash
curl -s -X POST https://api.idem.algoritful.com/v1/bind \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"embedding": [0.12, -0.54, 0.87, 0.33, -0.21, 0.66, -0.90, 0.44], "strictness": 0.55}'

# { "anchor": "0008a3f9...", "id": "f29c...", "dim": 8, "strictness": 0.55 }
2

Derive

Send a fresh embedding plus the stored anchor. Compare the returned id to the one you already saved.

bash
ANCHOR="YOUR_ANCHOR_FROM_BIND"
NEW_EMBED='[0.11, -0.55, 0.85, 0.30, -0.23, 0.68, -0.88, 0.42]'

curl -s -X POST https://api.idem.algoritful.com/v1/derive \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"embedding\": $NEW_EMBED, \"anchor\": \"$ANCHOR\"}"

# { "id": "f29c..." }  # compare to your stored id on your side

Common failures to handle.

The quickstart above is enough for integration. These are the main request errors you may want to surface or log.

Error reference

HTTPMessageCause
401UnauthorizedMissing or invalid Authorization header, or missing RapidAPI proxy headers when deployed behind RapidAPI
400embedding must not be emptySent []
400strictness must be between 0.0 and 1.0strictness out of valid range
400anchor is not valid hexCorrupted or truncated anchor string
400Dimension mismatchDerive embedding has different dim than bind
413Embedding exceeds 32 768 dimensions

Privacy properties for noisy embeddings.

The main operational properties teams usually care about in production.

UL

Unlinkability

Re-enrolling the same source generates fresh material, which makes cross-database linking much harder.

Distinct anchors across rebinds
IR

Irreversibility

The original embedding is not stored, and the anchor alone is not meant to serve as a recoverable template.

Original embedding not retained
NX

No exact-match brittleness

Close embeddings from the same source can still derive to the same ID even when exact hashing would split them apart.

Built for noisy observations
SL

Stateless API

The server stores nothing between calls. No session state, no template DB and no embedding retention on the API side.

Zero server-side storage
RV

Revocable

If material is ever exposed, bind again and issue a fresh anchor/id pair instead of replacing your encoder stack.

Rebind to rotate