API reference
The face recognition API is organized around REST. It accepts multipart form bodies for image uploads, returns JSON, and uses standard HTTP response codes. All requests must be made over HTTPS in production.
- Base URL
- https://tareef.g4t.io/api/v1
- Auth
- Bearer token
- Content type
- multipart/form-data
01 · Get started
Quickstart
Make your first verified call in under two minutes.
- Sign up (free) and create an API key.
- Enroll one or more people with reference photos.
- Verify a new photo against your library — done.
Every code sample on this page is runnable as written. The shell snippet below is the same shape every other endpoint uses.
POST
/api/v1/verify
curl -X POST https://tareef.g4t.io/api/v1/verify \
-H "Authorization: Bearer frs_live_XXXXXX" \
-F "file=@photo.jpg"
const form = new FormData();
form.append('file', file);
const res = await fetch('https://tareef.g4t.io/api/v1/verify', {
method: 'POST',
headers: { Authorization: 'Bearer frs_live_XXXXXX' },
body: form,
});
$res = Http::withToken('frs_live_XXXXXX')
->attach('file', file_get_contents($path), 'photo.jpg')
->post('https://tareef.g4t.io/api/v1/verify');
import requests
with open('photo.jpg','rb') as f:
res = requests.post(
'https://tareef.g4t.io/api/v1/verify',
headers={'Authorization': 'Bearer frs_live_XXXXXX'},
files={'file': f},
)
Official SDK · Laravel
Laravel SDK
Skip the raw HTTP plumbing. The first-party tareef/laravel package wraps every endpoint in a typed facade with typed exceptions and streamed multipart uploads.
The package is the recommended way to talk to Tareef from any Laravel app — PHP 8.2+, Laravel 10 / 11 / 12 / 13. Source on GitHub.
Install
composer require tareef/laravel
Configure
Set your key in .env — the service provider auto-discovers the rest.
TAREEF_API_KEY=frs_live_XXXXXX
Optional config keys: TAREEF_BASE_URL (defaults to https://tareef.g4t.io/api/v1), TAREEF_TIMEOUT, TAREEF_RETRIES, TAREEF_THROW_ON_QUOTA.
Image inputs
Any method that takes an image accepts:
Illuminate\Http\UploadedFile— straight from$request->file()SplFileInfo/Illuminate\Http\File— pre-moved files on diskstring— an absolute path
Uploads are streamed, never buffered into memory.
Typed exceptions
All errors inherit from TareefException. Catch the specific subclass when you care:
FaceAlreadyExistsException— duplicate face for this accountNoFaceDetectedException— no detectable face in the supplied imageQuotaExceededException— monthly verify quota hit (suppress withTAREEF_THROW_ON_QUOTA=false)AuthenticationException— bad / revoked API keyServiceUnavailableException— Tareef is down or unreachable
PHP
use Tareef\Laravel\Facades\Tareef
composer require tareef/laravel
# then in .env:
TAREEF_API_KEY=frs_live_XXXXXX
// The SDK is Laravel-only — see the JS tab on the rest of this page
// for fetch-based examples.
use Tareef\Laravel\Facades\Tareef;
use Tareef\Laravel\Exceptions\{NoFaceDetectedException, QuotaExceededException};
// Enroll someone from an uploaded file
$person = Tareef::register(
name: 'Jane Doe',
images: [$request->file('photo')],
phone: '+15555555555',
);
// Identify a face
try {
$result = Tareef::verify($request->file('selfie'));
if ($result->matched) {
return ['uuid' => $result->person->uuid, 'score' => $result->score];
}
} catch (NoFaceDetectedException) {
abort(422, 'No face in the photo.');
} catch (QuotaExceededException) {
abort(429, 'Monthly verify quota hit.');
}
# The SDK is Laravel-only — install the package on Packagist:
# https://packagist.org/packages/tareef/laravel
# For Python, use the raw REST examples on the rest of this page.
02 · Security
Authentication
Bearer your API key. We also accept x-api-key for legacy clients.
All authenticated endpoints require an Authorization header with a bearer token issued from your dashboard. Each key is bound to one account; revoking it disables access immediately.
- Format:
frs_live_followed by 32+ random characters. - Rotation: revoke keys you no longer use — they are shown once at creation.
- Failures return
401 unauthorizedwith no further details.
GET
/api/v1/people
# Pass the header on every request
Authorization: Bearer frs_live_XXXXXX
fetch('https://tareef.g4t.io/api/v1/people', {
headers: { Authorization: 'Bearer frs_live_XXXXXX' },
})
Http::withToken('frs_live_XXXXXX')
->get('https://tareef.g4t.io/api/v1/people')
requests.get(
'https://tareef.g4t.io/api/v1/people',
headers={'Authorization': 'Bearer frs_live_XXXXXX'},
)
03 · Resources
Enroll a person
Create a new person in your library from one or more reference photos.
/api/v1/people
multipart
Body parameters
namerequired string- Display name for the person.
phoneoptional string- Free-form identifier — phone, email, employee ID.
fileone of file- A single image (jpg, png, webp), up to 8 MB.
files[]one of file[]- Multiple images. Repeat the form key once per file. More samples means higher accuracy on future verifies.
Responses
- 200
success: truewith the newuuidandimages_registered. - 422
face_exists— the face is already enrolled for you. Existing UUID returned. - 422
no_face— no detectable face in any supplied image.
POST
/api/v1/people
curl -X POST https://tareef.g4t.io/api/v1/people \
-H "Authorization: Bearer frs_live_XXXXXX" \
-F "name=Jane Doe" \
-F "phone=+15555555555" \
-F "file=@photo.jpg"
const form = new FormData();
form.append('name', 'Jane Doe');
form.append('phone', '+15555555555');
form.append('file', file);
await fetch('https://tareef.g4t.io/api/v1/people', {
method: 'POST',
headers: { Authorization: 'Bearer frs_live_XXXXXX' },
body: form,
});
// Official SDK: composer require tareef/laravel
use Tareef\Laravel\Facades\Tareef;
$person = Tareef::register(
name: 'Jane Doe',
images: [$request->file('photo')],
phone: '+15555555555',
);
with open('photo.jpg','rb') as f:
requests.post(
'https://tareef.g4t.io/api/v1/people',
headers={'Authorization': 'Bearer frs_live_XXXXXX'},
data={'name':'Jane Doe','phone':'+15555555555'},
files={'file': f},
)
Resources
Add reference photos
Attach more photos to a person you’ve already enrolled.
/api/v1/people/{uuid}/images
multipart
POST
/api/v1/people/{uuid}/images
curl -X POST https://tareef.g4t.io/api/v1/people/UUID/images \
-H "Authorization: Bearer frs_live_XXXXXX" \
-F "files=@a.jpg" -F "files=@b.jpg"
const form = new FormData();
[a, b].forEach(f => form.append('files', f));
await fetch('https://tareef.g4t.io/api/v1/people/UUID/images', {
method: 'POST',
headers: { Authorization: 'Bearer frs_live_XXXXXX' },
body: form,
});
Http::withToken('frs_live_XXXXXX')
->attach('files', file_get_contents($a), 'a.jpg')
->attach('files', file_get_contents($b), 'b.jpg')
->post('https://tareef.g4t.io/api/v1/people/UUID/images');
with open('a.jpg','rb') as a, open('b.jpg','rb') as b:
requests.post(
'https://tareef.g4t.io/api/v1/people/UUID/images',
headers={'Authorization': 'Bearer frs_live_XXXXXX'},
files=[('files', a), ('files', b)],
)
Resources
Identify a face
Search every photo of every person in your library. Counts against your monthly quota.
/api/v1/verify
multipart
billable
Body parameters
filerequired file- The query image. We extract one embedding and return the best matching person.
Reading the score
The response includes a cosine score — lower is closer.
≤ 0.30very confident match≤ 0.38accepted match≤ 0.55uncertain> 0.55different person
Responses
- 200 match — returns
uuid,name,score,samples. - 200
not_found— below threshold or not in your library. - 200
no_face— no detectable face in the query image. - 429
quota_exceeded— monthly verification limit reached.
POST
/api/v1/verify
curl -X POST https://tareef.g4t.io/api/v1/verify \
-H "Authorization: Bearer frs_live_XXXXXX" \
-F "file=@photo.jpg"
const form = new FormData();
form.append('file', file);
const res = await fetch('https://tareef.g4t.io/api/v1/verify', {
method: 'POST',
headers: { Authorization: 'Bearer frs_live_XXXXXX' },
body: form,
});
const data = await res.json();
// Official SDK: composer require tareef/laravel
use Tareef\Laravel\Facades\Tareef;
$result = Tareef::verify($request->file('selfie'));
if ($result->matched) {
return [
'uuid' => $result->person->uuid,
'name' => $result->person->name,
'score' => $result->score,
];
}
import requests
with open('photo.jpg', 'rb') as f:
res = requests.post(
'https://tareef.g4t.io/api/v1/verify',
headers={'Authorization': 'Bearer frs_live_XXXXXX'},
files={'file': f},
)
print(res.json())
Resources
List people
Page through everyone you’ve enrolled, newest first.
/api/v1/people
Query parameters
limitoptional integer- Maximum rows to return. Defaults to
100.
GET
/api/v1/people
curl https://tareef.g4t.io/api/v1/people \
-H "Authorization: Bearer frs_live_XXXXXX"
const { people } = await fetch('https://tareef.g4t.io/api/v1/people', {
headers: { Authorization: 'Bearer frs_live_XXXXXX' },
}).then(r => r.json());
// Official SDK: composer require tareef/laravel
use Tareef\Laravel\Facades\Tareef;
$people = Tareef::list(limit: 100);
people = requests.get(
'https://tareef.g4t.io/api/v1/people',
headers={'Authorization': 'Bearer frs_live_XXXXXX'},
).json()['people']
Resources
Read & delete a person
Fetch a person record or remove them — and their embeddings — permanently.
Endpoints
- GET
/api/v1/people/{uuid}Returns the person record plus reference image paths. - DELETE
/api/v1/people/{uuid}Removes embeddings and stored photos. Irreversible.
GET
/api/v1/people/{uuid}
# Read
curl https://tareef.g4t.io/api/v1/people/UUID \
-H "Authorization: Bearer frs_live_XXXXXX"
# Delete
curl -X DELETE https://tareef.g4t.io/api/v1/people/UUID \
-H "Authorization: Bearer frs_live_XXXXXX"
// Read
const person = await fetch('https://tareef.g4t.io/api/v1/people/UUID', {
headers: { Authorization: 'Bearer frs_live_XXXXXX' },
}).then(r => r.json());
// Delete
await fetch('https://tareef.g4t.io/api/v1/people/UUID', {
method: 'DELETE',
headers: { Authorization: 'Bearer frs_live_XXXXXX' },
});
$person = Http::withToken('frs_live_XXXXXX')
->get('https://tareef.g4t.io/api/v1/people/UUID')
->json();
Http::withToken('frs_live_XXXXXX')
->delete('https://tareef.g4t.io/api/v1/people/UUID');
person = requests.get(
'https://tareef.g4t.io/api/v1/people/UUID',
headers={'Authorization': 'Bearer frs_live_XXXXXX'},
).json()
requests.delete(
'https://tareef.g4t.io/api/v1/people/UUID',
headers={'Authorization': 'Bearer frs_live_XXXXXX'},
)
04 · Limits
Rate limits & quotas
Verifications bill against your monthly quota. Enrollment, reads, and deletes are free. Quotas reset on the 1st of every calendar month at 00:00 UTC.
| Plan | Price | Verifications | People |
|---|---|---|---|
| Free | $0 | 100 / mo | 50 |
| Pro | $29 | 10,000 / mo | 5,000 |
| Business | $99 | 100,000 / mo | Unlimited |
Exceeding the quota returns 429 quota_exceeded with the current used and limit in the response body.
05 · Reference
Error codes
Every response includes a stable status string. Branch on that, not on HTTP codes alone.
| Status | HTTP | Meaning |
|---|---|---|
ok
|
200 | Successful response. |
not_found
|
200 / 404 | No matching person; or person UUID isn’t in your library. |
no_face
|
200 | We couldn’t detect a face in the supplied image. |
face_exists
|
422 | The face is already enrolled — existing UUID returned. |
invalid
|
422 | Request body is malformed or missing required fields. |
unauthorized
|
401 | Missing or revoked API key. |
quota_exceeded
|
429 | Plan limit reached for the calendar month. |
upstream_error
|
502 | The face recognition service was unreachable. |