Appearance
Passport Photo API
Generate a passport, visa, or ID photo from a portrait image and a document specification. The response includes the processed photo, its dimensions, and any detected photo-quality issues.
For details on how we process personal data, see Data Privacy.
Before you start
You need an API key and API secret, which you can get from the Dashboard. Send API requests from your server and keep both credentials out of browser code, mobile application bundles, source control, and logs.
Choose the API region configured for your account:
| Region | Base URL |
|---|---|
| United States | https://api-us.idphotoapp.com |
| European Union | https://api-eu.idphotoapp.com |
Other regional deployments may be available on request. Use the same region throughout a watermarked-preview flow.
All request examples use JSON and Content-Type: application/json.
Choose a calling mode
Direct result
Use POST /v2/makeIdPhoto when your backend should receive the final photo immediately.
text
Portrait + specCode → Final ID photoWatermarked preview
Use POST /v2/makeIdPhotoWatermark followed by POST /v2/getIdPhotoNoWatermark when your product needs a preview or payment step.
text
Portrait + specCode → Watermarked preview + photoUuid
photoUuid after confirmation → Final ID photoKeep the returned photoUuid on your server. It connects the preview to the final-photo request.
Quickstart
The following example creates a final UK passport photo directly. Replace the credential placeholders and the Base64 value before sending the request.
bash
curl --request POST \
--url https://api-us.idphotoapp.com/v2/makeIdPhoto \
--header 'Content-Type: application/json' \
--data '{
"apiKey": "your-api-key",
"apiSecret": "your-api-secret",
"imageBase64": "your-base64-encoded-image",
"specCode": "uk-passport",
"outputFormat": "IMAGE_BASE64"
}'A successful response includes a photoUuid, the selected specCode, output dimensions, an issues array, and either an image URL or Base64 image data according to outputFormat.
Health check
http
GET /v2/healthjson
{
"status": "GOOD"
}Create a final ID photo
http
POST /v2/makeIdPhotoRequest fields
| Field | Type | Required | Description |
|---|---|---|---|
apiKey | string | Yes | Your API key. |
apiSecret | string | Yes | Your API secret. |
imageBase64 | string | Yes | Base64-encoded source image. A data URI prefix is optional. |
specCode | string | Yes | Target document specification, for example uk-passport. |
outputFormat | string | No | S3_URL or IMAGE_BASE64. Defaults to S3_URL. |
issueSensitivityOverride | object | No | Overrides sensitivity for supported photo-quality checks. |
photoSheet | object | No | Requests printable sheets in one or more pixel sizes. |
Minimal request
json
{
"apiKey": "your-api-key",
"apiSecret": "your-api-secret",
"imageBase64": "your-base64-encoded-image",
"specCode": "uk-passport"
}Request with optional controls
This annotated example uses jsonc because it contains comments.
jsonc
{
"apiKey": "your-api-key",
"apiSecret": "your-api-secret",
"imageBase64": "data:image/jpeg;base64,...",
"specCode": "uk-passport",
"outputFormat": "IMAGE_BASE64",
"issueSensitivityOverride": {
// VERY_LOW, LOW, MEDIUM, HIGH, or VERY_HIGH.
// Higher values make the corresponding check stricter.
"ISSUE_FACE_LIGHT_NOT_BALANCE": "MEDIUM",
"ISSUE_FACE_BRIGHTNESS_BAD": "MEDIUM",
"ISSUE_PHOTO_SHARPNESS_BAD": "MEDIUM",
"ISSUE_HEAD_YAW_OVER_THRESHOLD": "MEDIUM",
"ISSUE_HEAD_PITCH_OVER_THRESHOLD": "MEDIUM",
"ISSUE_EYEGLASSES_NOT_ALLOWED": "MEDIUM",
"ISSUE_EYEGLASSES_REFLECTION": "MEDIUM",
"ISSUE_SUNGLASSES_NOT_ALLOWED": "MEDIUM",
"ISSUE_HAT_NOT_ALLOWED": "MEDIUM",
"ISSUE_BOTTOM_NOT_FULL": "MEDIUM",
"ISSUE_LEFT_NOT_FULL": "MEDIUM",
"ISSUE_RIGHT_NOT_FULL": "MEDIUM"
},
"photoSheet": {
// Each value is width*height in pixels. Up to 10 sizes may be requested.
"sheetSizes": ["1800*1200"]
}
}Sensitivity overrides affect issue detection. They do not change the selected document specification.
Response fields
Fields that do not apply to the selected output type may be null or omitted.
| Field | Type | Description |
|---|---|---|
photoUuid | string | Unique identifier for the processed photo. |
waterMark | boolean | Whether the returned photo contains a preview watermark. |
specCode | string | Specification used to create the photo. |
idPhotoUrl | string | Signed URL for the generated JPEG when URL output is used. |
idPhotoPngUrl | string | Signed URL for a PNG variant when available. |
idPhotoImageBase64 | string | Base64-encoded JPEG when Base64 output is requested. |
idPhotoPngImageBase64 | string | Base64-encoded PNG when requested and available. |
widthPx | integer | Output width in pixels. |
heightPx | integer | Output height in pixels. |
fileSize | integer | Output file size when available. |
photoWidthMm | integer | Approximate physical width in millimetres when available. |
photoHeightMm | integer | Approximate physical height in millimetres when available. |
photoDpi | integer | Output DPI from the selected specification. |
issues | array | Photo-quality issues detected during processing. An empty array means no listed issue was detected. |
idPhotoCode | string | Photo code when the selected specification supports one. |
photoSheet | object | Map from each requested sheet size to its generated sheet URL. |
jsonc
{
"photoUuid": "example-photo-uuid",
"waterMark": false,
"specCode": "uk-passport",
"idPhotoUrl": null,
"idPhotoImageBase64": "/9j/4AAQSkZJRgABAQ...",
"widthPx": 413,
"heightPx": 531,
"photoDpi": 300,
"issues": [],
"photoSheet": {}
}Create a watermarked preview
http
POST /v2/makeIdPhotoWatermarkThe request uses the same core fields as /v2/makeIdPhoto. The optional watermarkText field accepts only supported preview labels. Currently supported values are Preview and Aperçu, case-insensitively.
json
{
"apiKey": "your-api-key",
"apiSecret": "your-api-secret",
"imageBase64": "your-base64-encoded-image",
"specCode": "schengen-visa",
"watermarkText": "Preview"
}jsonc
{
"photoUuid": "example-photo-uuid",
"waterMark": true,
"specCode": "schengen-visa",
"idPhotoUrl": "https://example-signed-url",
"widthPx": 413,
"heightPx": 531,
"issues": []
}Save photoUuid; it is required to retrieve the final photo.
Retrieve the final photo
http
POST /v2/getIdPhotoNoWatermarkCall this endpoint after your user has confirmed the preview or completed your product's payment step.
| Field | Type | Required | Description |
|---|---|---|---|
apiKey | string | Yes | Your API key. |
apiSecret | string | Yes | Your API secret. |
photoUuid | string | Yes | Value returned by /v2/makeIdPhotoWatermark. |
photoSheet | object | No | Optional printable-sheet request. |
json
{
"apiKey": "your-api-key",
"apiSecret": "your-api-secret",
"photoUuid": "example-photo-uuid"
}The response uses the same output model as /v2/makeIdPhoto, with waterMark set to false.
jsonc
{
"photoUuid": "example-photo-uuid",
"waterMark": false,
"specCode": "schengen-visa",
"idPhotoUrl": "https://example-signed-url",
"widthPx": 413,
"heightPx": 531,
"photoDpi": 300,
"issues": [],
"photoSheet": {}
}Work with photo issues
The API may return a generated photo together with one or more entries in issues. Treat these entries as information your application should evaluate, not as transport-level request errors.
Recommended handling:
- If
issuesis empty, continue with your normal flow. - If issues are present, map them to clear instructions for the user.
- Ask the user to retake the photo when the issue cannot be corrected safely.
- Do not silently ignore issues for workflows that require strict photo quality.
See Issue Codes in API Responses and Common Mistakes from End Users.
Find a photo specification
Use the specification endpoints instead of maintaining a complete hard-coded list in your application.
List specifications
http
POST /v2/listIdPhotoSpecCodejson
{
"apiKey": "your-api-key",
"apiSecret": "your-api-secret"
}json
{
"results": [
{
"specCode": "us-passport",
"specCodeName": "US Passport"
}
],
"total": 1
}Get specification details
http
POST /v2/getIdPhotoSpecjson
{
"apiKey": "your-api-key",
"apiSecret": "your-api-secret",
"specCode": "us-passport"
}The response describes the selected specification, including its pixel dimensions, physical size, DPI, background, head-position guidance, and other document-specific properties when available.
json
{
"specCode": "us-passport",
"specCodeName": "US Passport",
"photoSizeUnit": "in",
"photoSize": "2 x 2 in",
"photoPixel": "600 x 600 px",
"photoDpi": "300 DPI",
"headHeight": "1 - 1 3/8",
"eyeToBottom": "1 1/8 - 1 3/8",
"backgroundColor": "#FFFFFF",
"backgroundColorName": "white",
"recency": "6 months",
"expression": "NEUTRAL",
"color": "IN_COLOR",
"glasses": "NOT_ALLOWED",
"eyesAndEars": "VISIBLE_NO_HIDE"
}See Spec Code for common examples.
Query account status
http
POST /v2/queryAccountStatusjson
{
"apiKey": "your-api-key",
"apiSecret": "your-api-secret"
}jsonc
{
"accountStatus": "SUBSCRIBED",
"subscription": {
"subscriptionStatus": "SUBSCRIPTION_COMPLETE",
"subscriptionResetTime": 1735689600,
"makeIdPhotoApiQuota": 100,
"makeIdPhotoWatermarkApiQuota": 1000,
"makeIdPhotoApiRemaining": 95,
"makeIdPhotoWatermarkApiRemaining": 998
}
}For a free-trial account, accountStatus is FREE_TRIAL and the response may include freeTrialEndTime. Timestamps are Unix timestamps in seconds.
Possible subscriptionStatus values are:
| Status | Meaning |
|---|---|
SUBSCRIPTION_PENDING | The subscription has been created but is not yet active. |
SUBSCRIPTION_COMPLETE | The subscription is active. |
SUBSCRIPTION_FAILED | Subscription setup or payment failed. |
SUBSCRIPTION_DELETED | The subscription was permanently deleted. |
SUBSCRIPTION_CANCELED | The subscription was canceled and may remain available until the end of its service period. |
Handle request errors
Use both the HTTP status and response body when handling failures. At minimum, distinguish between:
- invalid or missing credentials;
- malformed JSON or missing required fields;
- invalid Base64 image data;
- an unknown
specCode; - an unavailable or failed image-processing operation; and
- network timeouts.
Set a client-side timeout, avoid automatic retries for requests whose outcome is uncertain, and never log credentials or full Base64 image payloads.
