Introduction
While working with the Azure Face API to implement headshot validation, I encountered the following error during a face detection task:
Error during API call: (InvalidRequest) Invalid request has been sent.
This generic error provided no actionable information, making debugging difficult. To resolve the issue, I had to:
- Dig deeper into the FaceClient SDK.
- Enable logging to capture HTTP requests and responses.
- Eventually uncover the root cause: the
returnFaceId
parameter.
This post will walk you through:
- How I identified and resolved the issue.
- Why the
returnFaceId
parameter caused the error. - How to fix and debug similar issues in the Azure Face API.
- How to request approval for the
returnFaceId
feature. - How to directly invoke the API for maximum control.
If you’re interested in headshot validation, check out my earlier post: Headshot Validation Using Azure Face API with Python.
Initial Code
Here’s the initial code I was using for face detection:
try:
with open(image_path, "rb") as image_stream:
print("Sending image to Azure Face API...")
detected_faces = face_client.face.detect_with_stream(
image=image_stream,
detection_model="detection_03" # Modern detection model
)
except Exception as e:
print(f"Error during API call: {e}")
return False
The output:
Error during API call: (InvalidRequest) Invalid request has been sent.
This generic message made it hard to debug the issue. I had no idea whether the problem was with my parameters, the image, or the API itself.
Adding Logging to Debug
To get more details, I enabled HTTP logging to capture the raw request and response sent to the Azure Face API. Here’s the updated code:
import logging
logging.basicConfig(level=logging.DEBUG) # Enable detailed logging
try:
with open(image_path, "rb") as image_stream:
print("Sending image to Azure Face API...")
detected_faces = face_client.face.detect_with_stream(
image=image_stream,
detection_model="detection_03" # Modern detection model
)
except Exception as e:
if hasattr(e, 'response') and e.response is not None:
print("Error during API call:")
print(f"HTTP Status Code: {e.response.status_code}")
print(f"Response Body: {e.response.text}")
else:
print(f"Error: {e}")
return False
The logs provided invaluable insights into the API behavior:
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): xxxx.cognitiveservices.azure.com:443
DEBUG:urllib3.connectionpool:https://xxxx.cognitiveservices.azure.com:443 "POST /face/v1.0/detect?returnFaceId=true&returnFaceLandmarks=false&recognitionModel=recognition_01&returnRecognitionModel=false&detectionModel=detection_03&faceIdTimeToLive=86400 HTTP/11" 403 362
DEBUG:msrest.exceptions:(InvalidRequest) Invalid request has been sent.
Error during API call:
HTTP Status Code: 403
Response Body: {
"error": {
"code": "InvalidRequest",
"message": "Invalid request has been sent.",
"innererror": {
"code": "UnsupportedFeature",
"message": "Feature is not supported, missing approval for one or more of the following features: Identification,Verification. Please apply for access at https://aka.ms/facerecognition"
}
}
}
Root Cause: returnFaceId
Defaults to True
The returnFaceId parameter in the Azure FaceClient SDK defaults to True, meaning the API tries to generate and return a unique Face ID for each detected face. This Face ID serves as a temporary identifier for the detected face, enabling workflows like face recognition, verification, and finding similar faces. The Face ID represents the face’s extracted features and can be used in subsequent API calls to match or compare faces.
However:
- This feature is restricted to approved customers only.
- If you don’t have approval, the API rejects the request with an InvalidRequest error.
Since my application only required face detection (and not recognition tasks), I resolved the issue by explicitly setting return_face_id=False
:
detected_faces = face_client.face.detect_with_stream(
image=image_stream,
detection_model="detection_03",
return_face_id=False # Explicitly exclude Face ID
)
Directly Invoking the Azure Face API
If you prefer full control over your API parameters, you can bypass the SDK and call the Azure Face API directly. This avoids SDK defaults like returnFaceId=True
.
Using cURL
curl -X POST "https://your-endpoint.cognitiveservices.azure.com/face/v1.0/detect" \
-H "Content-Type: application/octet-stream" \
-H "Ocp-Apim-Subscription-Key: your_subscription_key" \
--data-binary "@your_image.jpg"
-H "Content-Type: application/octet-stream" \
-H "Ocp-Apim-Subscription-Key: your_subscription_key" \
--data-binary "@your_image.jpg"
Using Python requests
import requests
FACE_API_KEY = "your_subscription_key"
FACE_API_ENDPOINT = "https://your-endpoint.cognitiveservices.azure.com/face/v1.0/detect"
headers = {
"Content-Type": "application/octet-stream",
"Ocp-Apim-Subscription-Key": FACE_API_KEY
}
params = {
"detectionModel": "detection_03"
}
with open("your_image.jpg", "rb") as image_stream:
response = requests.post(FACE_API_ENDPOINT, headers=headers, params=params, data=image_stream)
print(response.json())
FACE_API_KEY = "your_subscription_key"
FACE_API_ENDPOINT = "https://your-endpoint.cognitiveservices.azure.com/face/v1.0/detect"
headers = {
"Content-Type": "application/octet-stream",
"Ocp-Apim-Subscription-Key": FACE_API_KEY
}
params = {
"detectionModel": "detection_03"
}
with open("your_image.jpg", "rb") as image_stream:
response = requests.post(FACE_API_ENDPOINT, headers=headers, params=params, data=image_stream)
print(response.json())
Direct API calls allow you to explicitly include or exclude parameters, ensuring greater flexibility.
How to Fix returnFaceId
Errors
Set return_face_id=False
:
- Unless your application requires face recognition workflows, explicitly exclude Face IDs:
detected_faces = face_client.face.detect_with_stream(
image=image_stream,
detection_model="detection_03",
return_face_id=False
)
Request Approval for returnFaceId
:
- Submit a request here: Request Face ID Access.
- Learn more about Azure’s limited-access features here: Limited Access Services.
Best Practices for Debugging Azure Face API
Enable Logging:
- Use Python’s
logging
module to capture HTTP requests and responses:
import logging
logging.basicConfig(level=logging.DEBUG)
Check API Documentation:
- Verify parameter compatibility in the Azure Face API Documentation.
Use cURL for Simple Tests:
- Test the API using
cURL
to isolate issues before implementing in Python.
Handle API Exceptions Gracefully:
- Extract and print detailed responses from exceptions:
if hasattr(e, 'response') and e.response is not None:
print(f"HTTP Status Code: {e.response.status_code}")
print(f"Response Body: {e.response.text}")
Conclusion
The returnFaceId
parameter is powerful for face recognition workflows but requires approval for use. If you don’t need face IDs, explicitly set return_face_id=False
to avoid errors. For advanced use cases requiring face IDs, submit a request for access.
By adding logging and carefully reviewing the API response, you can effectively debug and resolve issues in the Azure Face API, making it a reliable tool for tasks like headshot validation and face detection.
For a practical implementation of headshot validation, check out my post: Headshot Validation Using Azure Face API.