Tutorial

Getting Started with Face Detection: A Practical Tutorial

Learn how to detect faces in images with the APIShard Face Detector API.

A

APIShard Team

March 15, 2026 · 5 min read

Getting Started with Face Detection: A Practical Tutorial

Face detection is one of those computer vision tasks that feels complex on the surface but becomes straightforward with the right API. The APIShard Face Detector lets you upload an image and instantly get the coordinates, dimensions, and confidence scores for every detected face - no ML model training, no GPU required.

In this guide, we'll walk through three practical patterns: basic face detection, filtering results by confidence.

How Face Detection Works

When you send an image to the Face Detector API, it returns:

{
  "count": 2,
  "faces": [
    {
      "x": 120,
      "y": 85,
      "w": 95,
      "h": 110,
      "confidence": 0.98
    },
    {
      "x": 320,
      "y": 90,
      "w": 90,
      "h": 108,
      "confidence": 0.95
    }
  ]
}

Each face includes:

  • x, y: Top-left corner position (pixels)
  • w, h: Width and height (pixels)
  • confidence: Detection confidence score (0.0–1.0)

Pattern 1: Basic Face Detection with cURL

The simplest way to get started is a direct POST request with multipart form data:

curl -X POST "https://api.apishard.com/v1/face-detector" \
  -H "x-api-key: $APISHARD_KEY" \
  -F "[email protected]"

This returns the face count and bounding box data instantly.

Pattern 2: Detecting Faces in TypeScript

For production applications, you'll want to handle errors and process results:

import fs from "fs";
import path from "path";

interface Face {
  x: number;
  y: number;
  w: number;
  h: number;
  confidence: number;
}

interface DetectionResult {
  count: number;
  faces: Face[];
}

async function detectFaces(imagePath: string): Promise<DetectionResult> {
  const imageBuffer = fs.readFileSync(imagePath);
  const formData = new FormData();
  const blob = new Blob([imageBuffer], { type: "image/jpeg" });
  formData.append("image", blob, path.basename(imagePath));

  const response = await fetch("https://api.apishard.com/v1/face-detector", {
    method: "POST",
    headers: {
      "x-api-key": process.env.APISHARD_KEY!,
    },
    body: formData,
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Face detection failed: ${error.message}`);
  }

  return response.json();
}

// Usage
const result = await detectFaces("./photo.jpg");
console.log(`Found ${result.count} face(s)`);
result.faces.forEach((face, i) => {
  console.log(`Face ${i + 1}: confidence ${(face.confidence * 100).toFixed(1)}%`);
});

Pattern 3: Filter by Confidence Threshold

Not all detections are equal. In real applications, you'll often want to discard low-confidence results:

async function detectHighConfidenceFaces(
  imagePath: string,
  threshold: number = 0.85
): Promise<Face[]> {
  const result = await detectFaces(imagePath);
  return result.faces.filter((face) => face.confidence >= threshold);
}

// Usage: Only keep faces detected with 90% confidence or higher
const highConfidenceFaces = await detectHighConfidenceFaces("./photo.jpg", 0.9);
console.log(`High-confidence detections: ${highConfidenceFaces.length}`);

This pattern is essential for security-sensitive applications like facial recognition systems, where false positives can cause problems.

Supported Image Formats

The API accepts:

  • JPG / JPEG: Most common, good compression
  • PNG: Lossless, supports transparency
  • WebP: Modern format, excellent compression

Keep image sizes reasonable - while there's no strict limit, very large images may take longer to process.

Real-World Use Cases

Photo Albums & Galleries: Auto-tag faces and suggest organizing photos by person.

Content Moderation: Flag images containing faces for human review in user-generated content workflows.

Attendance Systems: Detect faces in captured photos to verify person-in-the-loop for time-tracking or security.

Accessibility: Generate face descriptions for visually impaired users ("Photo contains 2 faces").

Pricing & Credits

Each face detection call costs 10 credits. With a typical plan, you get a generous monthly allowance - check your dashboard for details. Bulk operations benefit from batching: use Promise.all() to parallelize uploads rather than processing images sequentially.

Error Handling

Always expect and handle these responses:

StatusCauseAction
200SuccessParse count and faces array
400Invalid image format or corrupted fileVerify the image is a valid JPG/PNG/WebP
401Missing or invalid API keyCheck your x-api-key header
403Insufficient creditsUpgrade your plan or wait for credit refresh
429Rate limit exceededImplement exponential backoff; see docs

Putting It Together

Here's a complete example that detects faces, filters by confidence, and logs results:

import fs from "fs";

async function processImage(imagePath: string): Promise<void> {
  console.log(`Processing: ${imagePath}`);

  const result = await detectFaces(imagePath);
  console.log(`Total detections: ${result.count}`);

  const highConfidence = result.faces.filter((f) => f.confidence >= 0.9);
  console.log(`High-confidence (≥90%): ${highConfidence.length}`);

  highConfidence.forEach((face, i) => {
    const area = face.w * face.h;
    console.log(
      `  Face ${i + 1}: ${face.w}×${face.h}px, area=${area}, conf=${(
        face.confidence * 100
      ).toFixed(1)}%`
    );
  });
}

// Run on all JPGs in a directory
const imageDir = "./photos";
fs.readdirSync(imageDir)
  .filter((f) => f.endsWith(".jpg"))
  .forEach((file) => processImage(`${imageDir}/${file}`));

Next Steps

  • Batch Processing: Combine face detection with other APIs (like Image to Text) to build richer insights.
  • Real-Time Streams: If you're processing video, send keyframes every N seconds to balance accuracy with cost.
  • Storage Integration: Save detection results to a database for historical analysis.

Check the full API docs for more details on response headers (credit usage), rate limits, and advanced options. Happy detecting!