Trace API v1
Reverse face search,
from your own code
Upload a face photo. Get back the public profiles it appears on, with a confidence score for each. One credit per search, no subscription, and the same engine the panel uses.
Quick start
Start a scan
curl -X POST https://traceaifacescan.app/api/v1/scans \
-H "Authorization: Bearer trk_live_YOUR_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-F [email protected]
202 Accepted
{
"id": "01m0jr1j5cbhwqsnt5qjx3zyd8",
"number": 1,
"status": "queued",
"progress": 0,
"locked": true,
"match_count": 0,
"credits_remaining": 9
}
Poll until it finishes
A search takes 25-45 seconds. Poll every second or two until
status is done
or failed.
curl https://traceaifacescan.app/api/v1/scans/SCAN_ID \
-H "Authorization: Bearer trk_live_YOUR_KEY"
200 OK
{
"id": "01m0jr1j5cbhwqsnt5qjx3zyd8",
"status": "done",
"progress": 100,
"locked": false,
"match_count": 2,
"matches": [
{
"score": 88,
"tier": "strong",
"platform": "x",
"handle": "@alexrivers88",
"url": "https://x.com/alexrivers88",
"preview_url": "https://traceaifacescan.app/api/v1/scans/01m0.../previews/0"
},
{
"score": 86,
"tier": "strong",
"platform": "instagram",
"handle": null,
"url": "https://www.instagram.com/p/DaAPjbsDTxV/",
"preview_url": "https://traceaifacescan.app/api/v1/scans/01m0.../previews/1"
}
]
}
handle is null when the URL points at a
post rather than an account. Two posts on one platform are two different
results, so they are not merged.
Authentication
Every request carries a key from the panel. There is no session, no cookie and no CSRF token — the key is the whole credential.
Authorization: Bearer trk_live_9F4KQ2M7…
A missing, malformed, revoked or unknown key all return the same
401. That is deliberate: telling them apart
would let anyone test whether a key exists.
Credits and previews
A scan started with credits available runs the search and returns real profile
links. With no credits the scan is created but no
search runs: it comes back locked: true
with match_count: 0 and an empty
matches array. Reveal it to spend a credit
and run the real thing.
The panel shows a signed-in visitor with no credits a static sample result, so they can see what a finished case looks like. The API never returns it — a placeholder is something a script would build on.
Revealing a locked scan is a separate call, never automatic: a script walking a list of scans should not be able to empty your balance by accident.
curl -X POST https://traceaifacescan.app/api/v1/scans/SCAN_ID/reveal \
-H "Authorization: Bearer trk_live_YOUR_KEY"
The credit is reserved when the search starts and returned automatically if it
fails. A scan that has already been revealed returns
200 and costs nothing.
Scans
/scans
Start a scan. multipart, field name image.
/scans
List your scans, newest first. Matches omitted.
/scans/{id}
One scan, with its matches.
/scans/{id}/reveal
Spend a credit and reveal the sources.
/scans/{id}/previews/{n}
The thumbnail of one match.
/scans/{id}
Delete the scan, its image and its previews.
The image
- jpeg, png or webp — at most 8 MB, at least 200×200 px.
- Crop to the face. A front-on, sharp, well-lit face is what makes a search work.
- There is no
image_urlparameter and there will not be one in v1 — fetching an arbitrary address on your behalf would make this endpoint an SSRF proxy.
Retries
Send an Idempotency-Key header when starting a
scan. The same key within 24 hours returns the original scan instead of
starting a second one — so a request that times out on your side can be retried
without paying twice.
Previews
preview_url needs the same
Authorization header. It is not a public
link and not a signed one: a shareable URL for a face image would outlive the
key it came from.
Account
/account
Your credit balance and this key's limits.
200 OK
{
"account_id": "TRC-4K7F-9QX2",
"credits": 9,
"scan_cost": 1,
"api_key": {
"name": "production server",
"prefix": "trk_live_9F4KQ2",
"rate_limit_per_min": 0
}
}
Errors
Errors are application/problem+json
(RFC 9457). Branch on code — it is part of the
contract. detail is written for humans and
may change without warning.
402 Payment Required
{
"type": "https://traceaifacescan.app/docs#insufficient_credits",
"title": "insufficient credits",
"status": 402,
"code": "insufficient_credits",
"detail": "Not enough credits to run the full search.",
"credits_remaining": 0
}
| STATUS | CODE | WHEN |
|---|---|---|
| 401 | unauthenticated | Missing, malformed, revoked or unknown key. |
| 402 | insufficient_credits | Reveal was called without enough credits. |
| 404 | not_found | No scan with that id on your account. |
| 409 | not_found | The query image was already deleted, so it cannot be revealed. |
| 422 | invalid_image | Wrong format, too large, or too small. |
| 429 | rate_limited | Over the limit. See the Retry-After header. |
| 500 | server_error | Our fault. Logged on our side. |
Failed searches
A search that starts and then fails is not an HTTP error — the scan comes back
with status: "failed" and an
error_code. The reserved credit is always
returned. Only no_face is something you can
fix, by sending a clearer photo.
Rate limits
There is no request rate limit. Call the API as fast as your code can. What actually costs something is a scan, and its limit is your credit balance — reads cost nothing and are not counted.
One ceiling remains and it is a security one, not a usage one: repeated
failed authentication attempts from the same address are throttled, so
guessing keys stays expensive. A valid key never sees it. If a single key ever
has to be capped we can set a per-key limit; when we do,
rate_limit_per_min on
GET /v1/account stops being
0 and responses start carrying
X-RateLimit-Limit and
X-RateLimit-Remaining.
Retention and rules
- Trace runs the search on its own engine, which queries public image search engines on your behalf. To do that the image is served from an unguessable address for up to 10 minutes while the search runs. Those engines keep their own caches, which we do not control.
-
Trace keeps the image and the results for
30 days,
then deletes both.
DELETE /scans/{id}does it immediately. - Images are stored outside the web root and served only through this API, under your own key.
- Only search photos you have the right to use, and follow the law where you are. By calling this API you take responsibility for that — see the Terms.