Hiface - Face Shape Prediction API Documentation
Overview
The Face Shape Prediction API is a comprehensive facial analysis platform that leverages state-of-the-art machine learning models to provide detailed insights about facial characteristics. Our system analyzes uploaded face images to determine face shape, detect age and gender, estimate BMI, and provide precise facial measurements with high accuracy.
π― Key Capabilities
- Face Shape Detection: Accurately identifies face shapes (oval, round, square, heart, rectangular, diamond)
- Demographic Analysis: Estimates age and gender with confidence scores
- BMI Estimation: Provides body mass index estimates based on facial features
- Facial Measurements: Detailed jaw shape, cheek structure, and face length analysis
- Real-time Processing: Fast inference with typical response times under 3 seconds
- High Accuracy: Confidence scores provided for all predictions
π οΈ Technology Stack
π§ Machine Learning
- TensorFlow deep learning framework
- Custom trained neural networks
- Computer vision algorithms
- Advanced facial landmark detection
π Backend Infrastructure
- Flask web framework
- RESTful API architecture
- SQLite database for user management
- Secure API key authentication
π§ Processing Pipeline
- Multi-stage face detection
- Facial landmark extraction
- Feature analysis and classification
- Real-time image processing
π¨ Use Cases
- Personalized product recommendations
- Virtual try-on experiences
- Beauty and fashion apps
- Health monitoring applications
- Fitness and wellness tracking
- Medical research tools
- Social media filters
- Dating app enhancements
- Gaming and AR applications
Authentication
The API uses API key authentication. All requests to protected endpoints must include an x-api-key
header.
Header Format
x-api-key: your-api-key-here
Endpoints
Face Analysis
POST /detect-face-shape
Description: Analyzes an uploaded face image and returns comprehensive facial analysis including shape, demographics, and measurements.
Headers:
Content-Type: multipart/form-data
x-api-key: your-api-key
Request Body:
- file: Image file (Required)
- Supported formats: PNG, JPEG, JPG, WEBP
- Must contain exactly one face
Success Response:
{
"status": "success",
"message": "Face shape detected successfully",
"data": {
"face_coordinates": {
"x": 150,
"y": 120,
"width": 300,
"height": 350
},
"thumbnail_face_crop_base64": "base64-encoded-thumbnail...",
"face_shape": "oval",
"face_shape_confidence": 0.87,
"all_face_shapes": {
"oval": 0.87,
"round": 0.08,
"square": 0.03,
"heart": 0.02
},
"jaw_shape": "soft",
"jaw_shape_confidence": 0.73,
"cheek_shape": "full",
"cheek_shape_confidence": 0.65,
"face_length": "medium",
"face_length_confidence": 0.81,
"bmi_estimate": 22.5,
"age_estimate": 28,
"age_confidence": 0.76,
"gender": "female",
"gender_confidence": 0.89,
"processing_time": 2.34,
"large_base64_image": "base64-encoded-full-image..."
}
}
Request/Response Formats
Supported File Formats
- PNG (.png)
- JPEG (.jpeg, .jpg)
- WEBP (.webp)
Face Shape Categories
Category | Description |
---|---|
oval | Oval face shape |
round | Round face shape |
square | Square face shape |
heart | Heart-shaped face |
rectangular | Rectangular face |
diamond | Diamond face shape |
Jaw Shape Categories
Category | Description |
---|---|
soft | Soft jawline |
angular | Angular jawline |
square | Square jawline |
Face Length Categories
Category | Description |
---|---|
short | Short face length |
medium | Medium face length |
long | Long face length |
Cheek Shape Categories
Category | Description |
---|---|
full | Full cheeks |
hollow | Hollow cheeks |
average | Average cheek structure |
Error Handling
Error Response Format
{
"status": "error",
"message": "Error description",
"error_code": "ERROR_CODE"
}
Common Error Codes
HTTP Code | Error | Description |
---|---|---|
400 |
Bad Request | Invalid request format or missing parameters |
401 |
Unauthorized | Invalid or missing API key |
415 |
Unsupported Media Type | Unsupported file format |
422 |
Unprocessable Entity | Multiple faces detected or no face found |
500 |
Internal Server Error | Server processing error |
Specific Error Examples
{
"status": "error",
"message": "No face detected in the uploaded image",
"error_code": "NO_FACE_FOUND"
}
{
"status": "error",
"message": "Multiple faces detected. Please upload an image with exactly one face",
"error_code": "MULTIPLE_FACES"
}
{
"status": "error",
"message": "Invalid API key",
"error_code": "INVALID_API_KEY"
}
Code Examples
import requests
def analyze_face(image_path, api_key):
url = "http://example.hiface.app/detect-face-shape"
headers = {"x-api-key": api_key}
with open(image_path, 'rb') as f:
files = {'file': f}
response = requests.post(url, files=files, headers=headers)
return response.json()
# Usage
api_key = "your-api-key-here"
result = analyze_face("path/to/image.jpg", api_key)
if result['status'] == 'success':
data = result['data']
print(f"Face Shape: {data['face_shape']}")
print(f"Confidence: {data['face_shape_confidence']}")
print(f"Age Estimate: {data['age_estimate']}")
print(f"Gender: {data['gender']}")
print(f"BMI Estimate: {data['bmi_estimate']}")
else:
print(f"Error: {result['message']}")
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
async function analyzeFace(imagePath, apiKey) {
const form = new FormData();
form.append('file', fs.createReadStream(imagePath));
try {
const response = await axios.post('http://example.hiface.app/detect-face-shape', form, {
headers: {
...form.getHeaders(),
'x-api-key': apiKey
}
});
return response.data;
} catch (error) {
throw new Error(error.response?.data?.message || error.message);
}
}
// Usage
(async () => {
try {
const apiKey = 'your-api-key-here';
const result = await analyzeFace('path/to/image.jpg', apiKey);
if (result.status === 'success') {
const data = result.data;
console.log(`Face Shape: ${data.face_shape}`);
console.log(`Confidence: ${data.face_shape_confidence}`);
console.log(`Age Estimate: ${data.age_estimate}`);
console.log(`Gender: ${data.gender}`);
console.log(`BMI Estimate: ${data.bmi_estimate}`);
}
} catch (error) {
console.error('Error:', error.message);
}
})();
# Analyze Face Image
curl -X POST http://example.hiface.app/detect-face-shape \
-H "x-api-key: your-api-key-here" \
-F "file=@path/to/image.jpg"
# Pretty print JSON response
curl -X POST http://example.hiface.app/detect-face-shape \
-H "x-api-key: your-api-key-here" \
-F "file=@path/to/image.jpg" | jq .
<?php
function analyzeFace($imagePath, $apiKey) {
$url = 'http://example.hiface.app/detect-face-shape';
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'x-api-key: ' . $apiKey
],
CURLOPT_POSTFIELDS => [
'file' => new CURLFile($imagePath)
]
]);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode !== 200) {
throw new Exception("HTTP Error: " . $httpCode);
}
return json_decode($response, true);
}
// Usage
try {
$apiKey = 'your-api-key-here';
$result = analyzeFace('path/to/image.jpg', $apiKey);
if ($result['status'] === 'success') {
$data = $result['data'];
echo "Face Shape: " . $data['face_shape'] . "\n";
echo "Confidence: " . $data['face_shape_confidence'] . "\n";
echo "Age Estimate: " . $data['age_estimate'] . "\n";
echo "Gender: " . $data['gender'] . "\n";
} else {
echo "Error: " . $result['message'] . "\n";
}
} catch (Exception $e) {
echo "Exception: " . $e->getMessage() . "\n";
}
?>
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
"path/filepath"
)
type FaceAnalysisResponse struct {
Status string `json:"status"`
Message string `json:"message"`
Data struct {
FaceShape string `json:"face_shape"`
FaceShapeConfidence float64 `json:"face_shape_confidence"`
AgeEstimate int `json:"age_estimate"`
Gender string `json:"gender"`
BMIEstimate float64 `json:"bmi_estimate"`
} `json:"data"`
}
func analyzeFace(imagePath, apiKey string) (*FaceAnalysisResponse, error) {
file, err := os.Open(imagePath)
if err != nil {
return nil, err
}
defer file.Close()
var body bytes.Buffer
writer := multipart.NewWriter(&body)
part, err := writer.CreateFormFile("file", filepath.Base(imagePath))
if err != nil {
return nil, err
}
_, err = io.Copy(part, file)
if err != nil {
return nil, err
}
writer.Close()
req, err := http.NewRequest("POST", "http://example.hiface.app/detect-face-shape", &body)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("x-api-key", apiKey)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var result FaceAnalysisResponse
err = json.NewDecoder(resp.Body).Decode(&result)
return &result, err
}
func main() {
apiKey := "your-api-key-here"
result, err := analyzeFace("path/to/image.jpg", apiKey)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
if result.Status == "success" {
fmt.Printf("Face Shape: %s\n", result.Data.FaceShape)
fmt.Printf("Confidence: %.2f\n", result.Data.FaceShapeConfidence)
fmt.Printf("Age Estimate: %d\n", result.Data.AgeEstimate)
fmt.Printf("Gender: %s\n", result.Data.Gender)
} else {
fmt.Printf("Error: %s\n", result.Message)
}
}
import Foundation
struct FaceAnalysisResponse: Codable {
let status: String
let message: String
let data: FaceData?
struct FaceData: Codable {
let faceShape: String
let faceShapeConfidence: Double
let ageEstimate: Int
let gender: String
let bmiEstimate: Double
enum CodingKeys: String, CodingKey {
case faceShape = "face_shape"
case faceShapeConfidence = "face_shape_confidence"
case ageEstimate = "age_estimate"
case gender, bmiEstimate = "bmi_estimate"
}
}
}
func analyzeFace(imagePath: String, apiKey: String, completion: @escaping (Result<FaceAnalysisResponse, Error>) -> Void) {
guard let url = URL(string: "http://example.hiface.app/detect-face-shape") else {
completion(.failure(NSError(domain: "Invalid URL", code: 0, userInfo: nil)))
return
}
guard let imageData = NSData(contentsOfFile: imagePath) else {
completion(.failure(NSError(domain: "File not found", code: 0, userInfo: nil)))
return
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue(apiKey, forHTTPHeaderField: "x-api-key")
let boundary = "Boundary-\(UUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
var body = Data()
body.append("--\(boundary)\r\n".data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg\"\r\n".data(using: .utf8)!)
body.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!)
body.append(imageData as Data)
body.append("\r\n--\(boundary)--\r\n".data(using: .utf8)!)
request.httpBody = body
URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
completion(.failure(error))
return
}
guard let data = data else {
completion(.failure(NSError(domain: "No data", code: 0, userInfo: nil)))
return
}
do {
let result = try JSONDecoder().decode(FaceAnalysisResponse.self, from: data)
completion(.success(result))
} catch {
completion(.failure(error))
}
}.resume()
}
// Usage
analyzeFace(imagePath: "path/to/image.jpg", apiKey: "your-api-key-here") { result in
switch result {
case .success(let response):
if response.status == "success", let data = response.data {
print("Face Shape: \(data.faceShape)")
print("Confidence: \(data.faceShapeConfidence)")
print("Age Estimate: \(data.ageEstimate)")
print("Gender: \(data.gender)")
} else {
print("Error: \(response.message)")
}
case .failure(let error):
print("Error: \(error.localizedDescription)")
}
}
Response Schema
Face Analysis Response
interface FaceAnalysisResponse {
status: "success" | "error";
message: string;
data?: {
face_coordinates: {
x: number;
y: number;
width: number;
height: number;
};
thumbnail_face_crop_base64: string;
face_shape: "oval" | "round" | "square" | "heart" | "rectangular" | "diamond";
face_shape_confidence: number; // 0.0 to 1.0
all_face_shapes: {
[shape: string]: number;
};
jaw_shape: "soft" | "angular" | "square";
jaw_shape_confidence: number;
all_jaw_shapes: {
[shape: string]: number;
};
cheek_shape: "full" | "hollow" | "average";
cheek_shape_confidence: number;
all_cheek_shapes: {
[shape: string]: number;
};
face_length: "short" | "medium" | "long";
face_length_confidence: number;
all_face_lengths: {
[length: string]: number;
};
bmi_estimate: number;
age_estimate: number;
age_confidence: number;
gender: "male" | "female";
gender_confidence: number;
processing_time: number; // seconds
large_base64_image: string;
};
error_code?: string;
}
Best Practices
Image Quality
- Use high-resolution images for better accuracy
- Ensure good lighting conditions
- Face should be clearly visible and not occluded
- Avoid blurry or distorted images
- Front-facing portraits work best
API Usage
- Store API keys securely
- Handle errors gracefully
- Implement retry logic for temporary failures
- Validate image format before uploading
- Consider implementing rate limiting on your side
Performance
- Process images on the client side to reduce file size if needed
- Use appropriate image formats (JPEG for photos, PNG for graphics)
- Consider image compression for faster uploads
- Monitor processing_time field for performance insights
Privacy & Security
π Data Protection & Privacy
We are committed to protecting your privacy and ensuring compliance with international data protection regulations including GDPR, CCPA, and other applicable privacy laws.
Image Data Handling
β No Image Storage Policy
- Images are not stored: All uploaded images are processed in real-time and immediately deleted from our servers after analysis
- Temporary processing only: Images exist in memory only during the analysis process (typically 2-5 seconds)
- No permanent storage: We do not maintain any database or file system storage of user images
- No backup copies: Images are never backed up, cached, or replicated to any storage system
Privacy Compliance
π GDPR Compliance (General Data Protection Regulation)
- Data Minimization: We only process the minimum data necessary for facial analysis
- Processing Lawfulness: Image processing is based on legitimate interest for providing the requested service
- Right to Erasure: Since images are not stored, there is no persistent data to erase
- Data Portability: No personal data is retained for portability requests
- Privacy by Design: Our system is designed with privacy as a core principle
πΊπΈ CCPA Compliance (California Consumer Privacy Act)
- No Sale of Data: We do not sell, rent, or share personal information with third parties
- No Data Collection: Since images are not stored, there is no collection of personal information
- Transparency: This documentation provides full transparency about our data handling practices
- Consumer Rights: No persistent data means no data to access, delete, or restrict
Security Measures
π‘οΈ Technical Security
- HTTPS Encryption: All data transmission is encrypted using TLS 1.2 or higher
- API Key Authentication: Secure API key-based authentication for all requests
- Memory-Only Processing: Images are processed in secure memory spaces
- Automatic Cleanup: Memory is automatically cleared after each processing cycle
- No Logging of Image Data: Our logs contain no image data or biometric information
π Access Control
- Rate Limiting: API requests are rate-limited to prevent abuse
- Authentication Required: All endpoints require valid API key authentication
- Request Validation: All inputs are validated and sanitized
- Audit Logging: API usage is logged (without image data) for security monitoring
Data Processing Details
Data Type | Purpose | Retention | Third Party Access |
---|---|---|---|
Face Images | Facial analysis processing | Deleted immediately after processing | None |
API Keys | Authentication and access control | Until revoked by administrator | None |
Usage Statistics | API monitoring and rate limiting | 30 days (metadata only) | None |
Error Logs | System monitoring and debugging | 7 days (no image data) | None |
User Rights & Contact
Your Rights
- Transparency: Full visibility into our data handling practices
- Control: You control what images are sent to our API
- No Profiling: We do not create profiles or track individuals
- Data Portability: N/A - No personal data is stored
- Right to Object: You can stop using the service at any time
β Privacy Summary
Zero Data Retention: Your images are processed and immediately deleted. We maintain no permanent record of your facial data, ensuring maximum privacy protection and compliance with all major data protection regulations.
Pricing
BASE Account
Perfect for small businesses
PRO Account
Best value for growing businesses
ENTERPRISE SOLUTIONS
Custom pricing and solutions for large organizations
Get a personalized quote for your needs
Billing Information
π³ Payment & Billing
- Monthly Billing: All plans are billed monthly with automatic renewal
- Minimum Commitment: The monthly minimum ensures your account remains active
- Overage Charges: Additional requests beyond included credits are charged at the per-request rate
- No Setup Fees: All plans include free account setup and API key generation
- Flexible Scaling: Upgrade or downgrade your plan at any time
π Usage Calculation
Example BASE Account:
- Monthly minimum: $100 (includes 2,000 credits)
- If you use 3,000 requests: $100 + (1,000 Γ $0.05) = $150 total
- If you use 1,500 requests: $100 total (within included credits)
Example PRO Account:
- Monthly minimum: $499 (includes 20,000 credits)
- If you use 30,000 requests: $499 + (10,000 Γ $0.03) = $799 total
- If you use 15,000 requests: $499 total (within included credits)
π Getting Started
Ready to start using the Face Shape Prediction API?
- Contact our team to discuss your usage requirements
- Choose the plan that best fits your needs (BASE, PRO, or ENTERPRISE)
- Complete the account setup process
- Receive your API key and start making requests
Standard Plans: Reach out to our development team to get started with BASE or PRO plans.
Enterprise Solutions: For custom enterprise pricing and solutions, contact us at support@appflows.co