People will take the photo on a phone, in a hallway, with the camera too close. Your app’s job is to catch that before you hand them a file they will submit to a passport office or a visa center. The ID Photo API does the crop, the specification, and the quality checks. You still own the camera screen, the copy, and the decision to ask for another photo.
This is the path we see work for consumer apps, kiosk software, travel platforms, and photo studios that embed capture in their own product. It uses the published Passport Photo API: one portrait, one specCode, a JPEG back, and an issues array you can turn into a sentence.
Put the camera in the app and the credentials on the server
The phone, the booth, or the browser should capture or upload a single color portrait. Encode it and send it to your backend. Your backend calls https://api-us.idphotoapp.com or https://api-eu.idphotoapp.com, whichever region the account uses. Other regions exist on request. Stay on one region for a given user, especially if you use the two-step preview flow.
The request carries apiKey and apiSecret. Both belong in server environment variables. The sample Python code reads them from the environment and sets a 120-second timeout on the HTTP client. Do not ship the secret in a mobile binary, a frontend bundle, or a log line. Do not log the Base64 image either. A passport portrait is personal data. The data privacy policy describes encrypted transmission, temporary URL storage from 2 hours to 14 days, and a Base64 option when you want the image only in your own systems.
Ask for a portrait the checks can actually use
Most failed submissions are capture problems, not API problems. The common mistakes guide is the list to turn into on-screen tips before the person taps the shutter:
- One person in the frame.
- Face in focus, lit evenly from the front. No hard shadow on the face or neck, no window behind them.
- Head upright, body square to the camera, eyes open, mouth closed.
- Camera far enough back that the full head, neck, and both shoulders are in the source. A tight crop of the face cannot be rescued by a later resize.
- An original color photo. A screenshot or a black-and-white image comes back as
ISSUE_NOT_IN_COLORor fails face detection.
Put that checklist on the capture screen. After the API responds, repeat only the line that matches the issue code.
Choose direct mode or a watermarked preview
Two calling modes are documented. Pick one per product surface. Do not mix them for the same photo.
Direct result
POST /v2/makeIdPhoto is the right call for a kiosk, a booth, an agency back office, or any backend that should store the final JPEG immediately. A minimal body is the key, the secret, the Base64 image, and the spec code. outputFormat is optional: S3_URL is the default, and IMAGE_BASE64 returns the JPEG in idPhotoImageBase64.
curl -sS -X POST "https://api-us.idphotoapp.com/v2/makeIdPhoto" \
-H "Content-Type: application/json" \
-d '{
"apiKey": "YOUR_API_KEY",
"apiSecret": "YOUR_API_SECRET",
"imageBase64": "BASE64_IMAGE",
"specCode": "uk-passport",
"outputFormat": "IMAGE_BASE64"
}'
A successful sample in the docs for uk-passport includes photoUuid, widthPx 413, heightPx 531, photoDpi 300, and an issues array. An empty array means the checks that ran did not report a problem. It does not mean a government office has approved the picture.
Watermarked preview
Consumer apps usually need a preview and a payment or confirmation step before the final file is released. That is two calls:
POST /v2/makeIdPhotoWatermarkwith the portrait and the spec code. OptionalwatermarkTextaccepts onlyPrevieworAperçu, case-insensitively. The response haswaterMark: trueand aphotoUuid.- After the person confirms,
POST /v2/getIdPhotoNoWatermarkwith thatphotoUuid. The final response haswaterMark: falseand the same kind of image fields as the direct call.
Store photoUuid on your server, tied to the user and the order. If you lose it, you cannot fetch the clean file. The watermark call and the final call must use the same regional host.
Select the document with a spec code
Do not hard-code “2 × 2 inches” or “35 × 45 mm” in the client and hope the crop matches. Send a specCode. The reference documents 150+ specifications and tells you to query them:
POST /v2/listIdPhotoSpecCodereturns codes and names. Examples in the docs includeus-passportanduk-passport.POST /v2/getIdPhotoSpecreturns pixel size, physical size, DPI, background color, head-height guidance, expression, and whether glasses are allowed, when the spec publishes those fields.
The US passport detail in the docs is a 2 × 2 in photo, 600 × 600 px, 300 DPI, white background, neutral expression, glasses not allowed. The UK passport print size used with photo codes is 35 × 45 mm. Schengen visa photos are a common third code, schengen-visa, and the watermark example in the reference uses it. Cache the list in your admin tool and let staff pick a document. Refresh the cache when you add a custom size. A custom employee-badge specification is how the employee badge photo API sets the photo window on a card. CR80 cards are 3.375 × 2.125 inches, and the portrait area depends on the template.
If you send a code the account does not have, the response can include ISSUE_PHOTO_SPEC_NOT_EXIST. Treat that as a configuration bug, not as a user mistake.
Turn issue codes into a retake, not a raw string
The issue code reference is the contract for the issues array. The codes that show up constantly in phone capture are:
ISSUE_FACE_NOT_FOUND— no usable face. Ask for one person, face fully visible.ISSUE_HEAD_YAW_OVER_THRESHOLDandISSUE_HEAD_PITCH_OVER_THRESHOLD— head turned or tilted. Ask them to face the camera and hold the head upright.ISSUE_EXPRESSION_NOT_NEUTRAL— mouth open or a broad smile. Ask for a closed mouth and a relaxed face. This is not an emotion score.ISSUE_EYEGLASSES_NOT_ALLOWEDandISSUE_EYEGLASSES_REFLECTION— glasses where the spec refuses them, or glare on the lenses.ISSUE_FACE_LIGHT_NOT_BALANCEandISSUE_FACE_BRIGHTNESS_BAD— uneven light, or a face that is too dark or too bright.ISSUE_PHOTO_SHARPNESS_BAD— blur. Ask for this before you nitpick framing.ISSUE_BOTTOM_NOT_FULL,ISSUE_LEFT_NOT_FULL,ISSUE_RIGHT_NOT_FULL— the source does not include enough shoulder. Ask them to step back.
When several codes return, show the one that forces a new photo first. The docs’ own example is to ask for a retake on a badly blurred image before you talk about a small positioning issue. Some checks accept issueSensitivityOverride with VERY_LOW through VERY_HIGH. Higher is stricter. Overrides change detection. They do not change the document specification. Do not quiet a check to push a government photo through.
HTTP failures are a different branch: bad credentials, malformed JSON, invalid Base64, an unknown spec, a processing failure, a timeout. A timeout is not proof the photo was skipped. The docs say to avoid an automatic retry until you know whether a result was created.
If the user is applying for a UK passport online, return a photo code
A UK online application asks for a photo code, which is a short HTTPS address for a JPEG you host. The applicant types it into the GOV.UK form. HM Passport Office retrieves the file and checks it. The mechanism is described on the GOV.UK photo code page for suppliers. A code is not an official endorsement.
On this API the field is idPhotoCode, shaped like idfoto.net/P5E9E47P. It is returned for uk-passport and uk-digital-passport. Direct mode returns it with the JPEG. Watermark mode returns it on getIdPhotoNoWatermark, after the preview, which is what you want if the code should only exist once the person has confirmed. Codes from this API stay retrievable for 21 days. That window is our hosting period. GOV.UK separately expects the photograph to have been taken in the last month. Confirm the current rule on GOV.UK’s photo guidance.
The digital photo rules also say the picture must be unedited. Crop and size, check the background and the detectable quality rules, and if the issue is the person’s expression, glasses, or pose, ask them to take another photo. The product page for that flow is the UK passport photo code API. Photo shops that want counter software, rather than an API, should use the studio workspace at passportphotocode.com. This article is the developer path.
Background removal and enhancement are optional steps
You often do not need a separate background call. The specification you send already carries a background color, and makeIdPhoto produces the finished file. Call background removal when you specifically need a transparent PNG first: POST /v2/removeBackground when edge quality matters, or POST /v2/removeBackgroundFast for a lower-latency preview. The request needs a data-URI prefix, outputFormat of PNG or JPEG, and outputType IMAGE_BASE64. JPEG cannot keep transparency. The cutout is not a passport photo until you run a spec code.
Soft or noisy captures can go through photo enhancement (POST /v2/photoEnhance) or shadow removal (POST /v2/removeShadow). scaleFactor defaults to 1. enableFaceEnhance defaults to false because it can change small details. Neither endpoint decides that a photo meets a passport rule. For a US or UK passport, do not use them to “fix” the person. The US Department of State says not to upload a photo created or edited with artificial intelligence or other digital tools. UK rules require an unedited digital photo.
The AI Photo Editing API (POST /v2/aiEdit) can correct pose, expression, glasses, lighting, recoverable blur, and a cut-off shoulder on a single portrait, while trying to keep the person recognizable. Access may need to be enabled. It does not select a document size, and it does not guarantee acceptance. AI-edited photos are not acceptable for US or UK passports. Use that endpoint for employee badges, member cards, and other workflows whose own policy allows a corrected portrait. For a government passport, detect the issue and send the person back to the camera.
Compare two faces only when that is actually the question
Some apps want to know whether the ID photo matches a selfie already on the account. That is POST /v2/faceMatch, documented on the Face Match API page. You send sourceImageBase64 and targetImageBase64. The response is isMatch and similarity. Omit similarityThreshold to use the account configuration, or send one you have tested on your own cameras. The score is not comparable with another vendor’s score, and a match is not a legal identity decision. The reference does not include liveness, document OCR, or anti-spoofing. Run issue codes first so a blurry frame is a retake rather than a mysterious non-match.
A large set of portraits, a school, or an employee directory is the same makeIdPhoto call in a queue you operate. There is no bulk-upload method. Read POST /v2/queryAccountStatus for makeIdPhotoApiRemaining before you start. The batch ID photo page describes that loop. If someone needs paper, add photoSheet.sheetSizes (up to 10 sizes, each width*height in pixels) and download the sheet URLs. Postage is not a field on the request. Confirm any mailing arrangement with support before you sell it. Details are on the print and mailing page.
A sequence you can ship
- Create a key in the dashboard. Store the key and secret on the server. Note whether the account is on the US or EU host.
- In the app, collect the document type. Map it to a
specCodeyou have confirmed withgetIdPhotoSpec. - Show the capture checklist. Accept one color image of one person.
- Upload the image to your server. For a paid consumer app, call
makeIdPhotoWatermark. For a kiosk or an internal tool, callmakeIdPhoto. - If
issuesis not empty, map the codes to one retake instruction and stay on the camera step. Do not show the raw code. - If the preview looks right and the user confirms, call
getIdPhotoNoWatermarkwith the savedphotoUuid. - For a UK online passport, display
idPhotoCodeand tell the person to enter it on GOV.UK. Tell them the code is retrievable for 21 days and that HMPO still checks the photo. - Persist
photoUuid, the spec code, and the issue list in your database. Copy image bytes into your own storage if you need them beyond the temporary URL window. - Watch
queryAccountStatusso a quota failure is an operator alert, not a generic “try again” for the traveler.
That is the whole product surface: a camera, a spec, a preview, a retake, and a file or a code. Headshot generation is a different endpoint, POST /api/generate-portrait, and it must not be wired into this flow. Generated portraits are not document photos. The AI headshot API page is for directory portraits and studio styles, with a prompt, a seed, and one to eight samples.
What to tell the person holding the phone
Say three things in the interface. The photo was sized for the document they selected. If there is an issue, say what to change: light, distance, expression, or glasses. For a government document, say that you checked the capture and the issuer still reviews it. For a UK code, show the code string and point them at the official application. For a US or UK passport, do not offer an “auto-fix my face” button. The boundary is documented on fix passport photo problems.
FAQ
Which endpoint creates the passport photo?
POST /v2/makeIdPhoto returns the final JPEG for one portrait and one spec code. Consumer apps that need a preview first call POST /v2/makeIdPhotoWatermark and then POST /v2/getIdPhotoNoWatermark with the photoUuid.
How do I know which spec code to send?
Call POST /v2/listIdPhotoSpecCode and POST /v2/getIdPhotoSpec. The reference documents 150+ specifications, including us-passport, uk-passport, and schengen-visa. Do not hard-code a millimeter size in the client and skip the spec.
Does an empty issues array mean the passport office will accept the photo?
No. It means the checks that ran did not report a listed problem. The issuing authority still reviews the photo. A UK photo code is not an acceptance decision either.
Can I correct a bad US or UK passport photo with AI?
No. US rules reject photos created or edited with artificial intelligence or other digital tools. UK digital photos must be unedited. Detect the problem and ask for a new capture. AI editing is for workflows such as employee badges where a corrected portrait is allowed.
Where should the API key live?
On your server. The secret must not ship in a browser app or a mobile binary, and you should not log the secret or the full Base64 image. Use the US or EU host configured for the account, and keep both steps of a watermarked flow on that same host.