API reference
The same five tools the dashboard runs, callable from your own code. Every call spends one operation from the monthly allowance your plan already includes — there is no separate API bill and no per-call price to work out.
Base URL
https://api.quantilence.com
Every endpoint is a POST that takes multipart/form-data and answers with JSON. There is no SDK to install; anything that can upload a file can call this.
Authentication
Send your key as a bearer token on every request:
Authorization: Bearer ql_live_…
- Keys are created on the API keys page and shown once. We store a hash, so a lost key is replaced rather than recovered.
- Server-side only. A key in browser code is public to everyone who loads the page. Cross-origin requests are refused for exactly that reason — proxy through your own backend.
- Revoking a key stops it working on the very next request. There is no cache to wait out.
- API keys are included on every account. See pricing.
Your first call
Reading text out of an image, in whichever language you work in:
curl -X POST https://api.quantilence.com/v1/ocr/extract \
-H "Authorization: Bearer $QUANTILENCE_API_KEY" \
-F "image=@photo.jpg" \
-F "language=en"Endpoints
Extract text
Read text out of a scan, photo or screenshot, with per-word confidence.
POST /v1/ocr/extract
Blur faces
Anonymise faces in an image, optionally keeping people you have enrolled sharp.
POST /v1/face-blur/process
Compare faces
Score how alike the faces in two images are.
POST /v1/face-similarity/match
Detect faces
Find every face in an image and get boxes plus aligned crops.
POST /v1/face-recognition/detect
Enrol a face
Add a face to a collection so it can be searched for or recognised later.
POST /v1/face-embeddings/sync
Search a collection
Find the enrolled faces that match a query photo.
POST /v1/face-search/query
Errors
There are two error envelopes, and handling only one is the most common integration bug against this API. Authentication and billing come from the gateway; anything about the file you sent comes from the model service, in a different shape.
{ "message": string, "type": string }Authentication, your plan, your allowance, rate limits.
{ "detail": { "code": string, "message": string } }Anything about the file you sent — unreadable, too large, no face in it.
{ "detail": string }A few older paths answer with a bare string. Handle both.
Read type or detail.code to branch on — both are stable. message is written for a person and may be reworded.
| Status | What it means |
|---|---|
| 400 empty_image · unreadable · bad_threshold · unknown_mode | The request was malformed — an empty upload, an image we could not decode, or a parameter outside its range. `detail.code` says which. |
| 401 invalid_api_key | No key, a malformed key, or one that has been revoked. Deliberately the same answer for all three, so the response cannot be used to learn which keys exist. |
| 402 quota_exceeded | Your monthly allowance is spent and you have no credits left. Buying credits or upgrading takes effect immediately; nothing else clears it until the period resets. |
| 403 api_access_revoked | Your plan no longer includes API keys — typically after a downgrade. The key itself is untouched and starts working again the moment the plan does. |
| 404 | That path is not part of the API. The same answer is given for endpoints that exist but are not exposed, so probing reveals nothing. |
| 409 duplicate_found | Enrolment only. This face is already in the collection. Set `check_duplicate` to false to add it anyway. |
| 415 unsupported_type | The upload was not an image format we can decode. |
| 422 no_face | The image decoded fine but contains no detectable face. Returned by comparison, search and enrolment — it is the most common failure in normal use, and it is not an error in your code. |
| 429 key_rpm_exceeded | This key exceeded 120 requests in a minute. Wait for the Retry-After it sends. |
| 429 key_daily_exceeded | This key exceeded 20,000 requests in a day. |
| 429 rpm_limit_exceeded | Your account exceeded 100 requests in a minute, counted across every key and the dashboard together. |
| 429 daily_limit_exceeded | Your account exceeded its daily request ceiling. |
| 429 monthly_limit_exceeded | Your account exceeded its monthly request ceiling. |
| 500 encode_failed | We could not produce the result image. Retry; the operation is not charged. |
| 502 | The model service could not be reached. Retry with a short backoff; the operation is not charged. |
| 503 redis_read_failed | Rate limiting was briefly unavailable, so the request was refused rather than let through uncounted. Retry. |
| 503 | Authentication was briefly unavailable. We fail closed here on purpose: an identity we cannot establish is not served. |
A failed operation is refunded: if we return a 5xx, the operation is not counted against your allowance.
Rate limits
Two ceilings, both well above ordinary use. They are abuse limits rather than billing controls — what you may actually run is your plan allowance.
- Per key: 120 requests a minute, 20,000 a day.
- Per account: 100 requests a minute across every key and the dashboard together.
Exceeding either returns 429 with a Retry-After header. Honour it rather than retrying immediately.
Ready to try it? Create a key and the quickstart above works as-is.
Get a key