Developer-friendly code & integrations
Drop PreCheck's facial recognition into your product with a single POST request. Copy-paste snippets for every stack.
One POST request
Send an image, get facial recognition results back — no SDK, no setup.
Every stack
Copy-paste snippets for JavaScript, Node.js, Python, PHP, and cURL.
A different dataset
Searches run on our own face index plus additional search sources, merged into one reply.
$1 per search
Pay as you go with credits. No subscription, and every plan includes API access.
Get Your API Key: Sign up at sys.precheck.ai to get your API key and start integrating. Each new search uses 1 credit; sending the same image again returns its saved results at no extra cost.
API Endpoint
Method: POST
Endpoint:
/api/search
Authentication: API key via query parameter
?api_key=YOUR_API_KEY
Code Examples
Copy and paste these code snippets into your project. Replace
YOUR_API_KEY
with your actual API key.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
imageUrl
|
String (URL) | Optional* | URL of the image to verify. Use this, imageFile, or pastedImage. |
imageFile
|
File | Optional* | Direct file upload (multipart/form-data). Use this, imageUrl, or pastedImage. |
pastedImage
|
String (Base64) | Optional* | Base64 encoded image data. Use this, imageUrl, or imageFile. |
return_url
|
Boolean | No | If true, the reply carries a url to the shareable results page instead of the list of matches. If false or omitted, the matches are returned. |
* At least one image parameter
(imageUrl,
imageFile, or
pastedImage) is required.
Example Response
Successful response when
return_url is
false or omitted. There is one
entry per matching face: its similarity
score (0–100), the page it was found on,
and a thumbnail.
{
"success": true,
"results": [
{
"score": 92,
"url": "https://example.com/page-where-the-face-appears",
"image_base64": "<base64-encoded thumbnail of the match>"
}
],
"error": ""
}
When return_url is
true, the reply carries a link to
the results page instead, ready to open or share:
{
"success": true,
"results": [],
"error": "",
"url": "https://sys.precheck.ai/results/AbC123xYz789"
}
Error Handling
Every reply is JSON. When a search can't run,
success is not
true and
error says why. Check that field
rather than the HTTP status code.
| error | What it means |
|---|---|
API key is required.
|
No api_key was sent. |
Invalid API key.
|
The key does not belong to an account. |
Insufficient balance.
|
The account is out of credits. Top up on the Pricing page. |
No image provided.
|
None of imageUrl, imageFile or pastedImage was sent. |
Invalid image URL provided.
|
imageUrl is not a valid URL. |
Only http and https image URLs are allowed.
|
imageUrl uses a different scheme. |
Image URL must point to a public address.
|
imageUrl points to a private or local network address. |
Failed to download image.
|
The image at imageUrl could not be fetched. |
no_results
|
The search ran but found no matching faces. |
Use PreCheck with Claude & OpenAI
PreCheck is a plain REST endpoint, so any model with function calling can run a face
search. Describe the endpoint once as a tool, execute the request when the model asks
for it, and hand the JSON back. Same idea on both platforms — only the wrapper differs
(input_schema
on Claude, parameters on OpenAI).
POST /api/search
is all Claude or OpenAI needs. An MCP server is optional — build one only if you want a
plug-and-play PreCheck connector for MCP apps (Claude Desktop, Cursor, and others) with no
per-app glue code. It wraps this same endpoint; it doesn't unlock anything the REST API can't
already do.
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic();
// 1. Describe PreCheck as a tool Claude can call
const tools = [{
name: 'precheck_face_search',
description:
'Search for a face across the web with PreCheck. Call this ' +
'when the user gives a photo URL of a person and wants to find ' +
'where that face appears online or verify an identity.',
input_schema: {
type: 'object',
properties: {
imageUrl: { type: 'string', description: 'Public image URL.' },
return_url: { type: 'boolean', description: 'Return only the result URL.' }
},
required: ['imageUrl']
}
}];
// 2. Run the search when Claude asks for it
async function precheckFaceSearch(input) {
const res = await fetch(
'https://sys.precheck.ai/api/search?api_key=' + process.env.PRECHECK_API_KEY,
{ method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(input) });
return res.json();
}
const msg = await client.messages.create({
model: 'claude-opus-5',
max_tokens: 1024,
tools,
messages: [{ role: 'user',
content: 'Find where this face appears: https://example.com/face.jpg' }]
});
// When msg.stop_reason === 'tool_use', call precheckFaceSearch() with the
// tool input, then send the result back as a { type: 'tool_result' } block.
import OpenAI from 'openai';
const openai = new OpenAI();
// Same PreCheck endpoint, described as an OpenAI function
const tools = [{
type: 'function',
function: {
name: 'precheck_face_search',
description:
'Search for a face across the web with PreCheck. Use when the ' +
'user provides a photo URL and wants to find where it appears online.',
parameters: {
type: 'object',
properties: {
imageUrl: { type: 'string', description: 'Public image URL.' },
return_url: { type: 'boolean', description: 'Return only the result URL.' }
},
required: ['imageUrl']
}
}
}];
const res = await openai.chat.completions.create({
model: 'gpt-4o', // or any function-calling model
messages: [{ role: 'user',
content: 'Find where this face appears: https://example.com/face.jpg' }],
tools
});
// When res.choices[0].message.tool_calls is set, POST the arguments to
// https://sys.precheck.ai/api/search?api_key=YOUR_API_KEY and return the
// JSON to the model as a { role: 'tool' } message.
Ship your first search today.
Grab your API key and send a single POST request — you'll have facial recognition results in seconds.