Lompat ke contoh kode
Tandarupa Sandbox

API verifikasi wajah

Verifikasi wajah dari server Anda: kirim foto terdaftar dan foto baru ke compare, lalu Tandarupa mengembalikan skor kemiripan keduanya. Foto tidak disimpan di server kami, dan batas lolosnya ditentukan oleh aplikasi Anda.

Respons compareJSON
{
  "request_id": "req_5fa5000a58c44a9eb3ea",
  "model": "tr1",
  "face": {
    "count": 1, "box": [139, 217, 223, 298], "confidence": 0.9323
  },
  "reference_face": {
    "count": 1, "box": [119, 113, 170, 240], "confidence": 0.9299
  },
  "similarity": 0.5887  // -1 sampai 1
}

Mulai

Satu request dari server Anda berisi foto terdaftar dan foto baru.

Compare
curl https://sandbox-tandarupa.instrumeta.id/v1/compare \
  -H "Authorization: Bearer $TANDARUPA_KEY" \
  -F reference_photo=@foto-terdaftar.jpg \
  -F photo=@foto-baru.jpg
Enroll dan verify untuk volume besar

Daftarkan wajah sekali dengan enroll dan simpan enrollment dari responsnya. Setelah itu, verify hanya memproses foto baru, sehingga dua kali lebih cepat daripada compare.

1. Enroll
curl https://sandbox-tandarupa.instrumeta.id/v1/enroll \
  -H "Authorization: Bearer $TANDARUPA_KEY" \
  -F photo=@foto-terdaftar.jpg
Respons enrollJSON
{
  "request_id": "req_1e27f73d5165488fb11f",
  "model": "tr1",
  "face": {
    "count": 1, "box": [119, 113, 170, 240], "confidence": 0.9299
  },
  "enrollment": "tr1.eltBPxlE..."  // data pendaftaran wajah, simpan terenkripsi
}
2. Verify
curl https://sandbox-tandarupa.instrumeta.id/v1/verify \
  -H "Authorization: Bearer $TANDARUPA_KEY" \
  -F photo=@foto-baru.jpg \
  -F enrollment="tr1.eltBPxlE..."

API key sandbox berawalan tr_test_. Simpan key hanya di server, jangan di aplikasi mobile. Setiap respons menyertakan header X-Request-Id; sertakan nilainya saat melaporkan masalah.

Membaca skor

Tandarupa tidak menentukan lolos atau tidak. Ambang batas ditentukan oleh aplikasi Anda.

Kemiripan (similarity) adalah cosine similarity dengan rentang -1 sampai 1. Makin tinggi ambang, makin sedikit orang berbeda yang lolos, tetapi makin sering orang yang sama ditolak. Angka di tabel diukur pada dataset publik LFW yang berisi foto berita tokoh publik, bukan selfie, jadi kalibrasi ulang dengan foto pengguna Anda.

Diukur pada 5.885 pasangan foto LFW: 2.944 pasangan orang berbeda dan 2.941 pasangan orang yang sama.
AmbangOrang berbeda yang lolosOrang sama yang ditolak
0,3632 dari 2.9442,2%
0,401 dari 2.9443,0%
0,450 dari 2.9445,3%
0,500 dari 2.9449,3%

Server Tandarupa tidak mendeteksi foto palsu, sehingga foto dari cetakan atau layar HP dapat lolos. SDK Flutter meminta dua gerakan acak (toleh, kedip, atau senyum) sebelum foto diambil. Untuk keputusan yang penting, tambahkan pengambilan foto yang diawasi atau pemeriksaan oleh manusia.

Jangan tampilkan similarity di aplikasi pengguna akhir, karena skor tersebut dapat dipakai untuk mencoba berulang kali hingga lolos.

SDK Laravel dan Flutter

Verifikasi wajah di Laravel cukup satu panggilan dari server Anda. Di aplikasi, SDK Flutter untuk verifikasi wajah meminta dua gerakan acak lalu memotret, tanpa menyimpan API key.

Laravel 12 dan 13, PHP 8.2+
$result = $tandarupa->compare(
    $request->file('photo')->get(),
    Storage::get($user->photo_path),
);

// Sesuaikan ambang dengan data Anda.
$passed = $result->similarity >= 0.40;
Flutter 3.24+
// Meminta dua gerakan acak, lalu memotret.
final photo = await TandarupaCapture.open(context);
if (photo == null) return; // pengguna membatalkan

// Kirim photo.bytes ke server Anda
// sebagai field multipart "photo".
Instalasi
Laravel
composer require tandahari/tandarupa
Flutter
flutter pub add tandarupa

Isi TANDARUPA_API_KEY di .env server Laravel. Di Android, aplikasi memerlukan izin kamera, minSdk 23, dan compileSdk 35. Di iOS, aplikasi memerlukan iOS 15.5 atau lebih baru dan NSCameraUsageDescription.

Error dan batas

Setiap error memiliki kode tetap dan pesan dalam bahasa Indonesia. Error tentang satu foto menyertakan field yang menyebut fotonya.

KodeHTTPArti
UNAUTHORIZED401API key tidak ada, salah, atau sudah dicabut
NO_FACE422Tidak ada wajah yang terdeteksi
MODEL_MISMATCH422Data pendaftaran wajah dibuat oleh versi model lain. Lakukan enroll ulang.
IMAGE_TOO_LARGE413Foto lebih dari 5 MB atau 4096×4096 piksel
ENGINE_BUSY503Antrean penuh. Ulangi setelah jeda singkat.
Semua kode error dan batas
INVALID_REQUEST400Field wajib tidak diisi
INVALID_IMAGE400Foto tidak dapat dibaca
UNSUPPORTED_MEDIA_TYPE415Format foto bukan JPEG atau PNG
INVALID_ENROLLMENT422Data pendaftaran wajah rusak atau tidak valid
ENGINE_UNAVAILABLE503Engine gagal memproses. Request boleh diulang.
NOT_FOUND404Endpoint tidak ditemukan
METHOD_NOT_ALLOWED405Metode HTTP tidak didukung
  • Foto berformat JPEG atau PNG, maksimal 5 MB dan 4096×4096 piksel. Orientasi EXIF diterapkan oleh server.
  • Jika foto berisi beberapa wajah, wajah terbesar yang diproses dan face.count berisi jumlah wajah.
  • Rate limit: 5 request per detik per API key (burst 10) dan 10 request per detik per alamat IP (burst 20). Request yang melebihi batas mendapat status 429 tanpa body JSON.
  • Request body di atas 11 MB ditolak gateway sebelum sampai ke layanan. SDK Laravel mengecilkan foto yang melebihi batas sebelum mengirim.

Data dan kontak

  • Foto diproses di memori lalu dibuang. Log hanya mencatat waktu, kode, dan durasi, tanpa foto, data pendaftaran wajah, atau skor.
  • Data pendaftaran wajah termasuk data biometrik. Simpan dalam bentuk terenkripsi dan minta persetujuan pengguna sebelum mendaftarkan wajahnya.
  • Untuk keputusan yang berdampak pada hak seseorang, sediakan pemeriksaan oleh manusia.

Untuk meminta API key atau melaporkan masalah, hubungi tim Instrumeta melalui WhatsApp 0896 8232 1590 atau email admin@instrumeta.id. Sertakan request_id saat melaporkan masalah.