How to map visa photo requirements by country in a travel or visa-agency app

A visa desk sells a file for a specific application: a Schengen short-stay visa, a US visa, a national passport, sometimes two of those from the same sitting. Pixel size, background, head height, and glasses rules differ. A travel app that hard-codes 35 × 45 mm, or a worker that runs every portrait through us-passport, hands the traveler a crop the form cannot use.

The ID Photo API sizes one portrait to one specCode after you have read that code from the account. This article is the catalog, the destination map, and the request. Camera placement and the watermarked preview are in how to add passport photo capture to your app. Keep that flow. Change the document you ask for.

Keep a catalog, not a millimetre constant

The spec code reference documents 150+ photo specifications, including us-visa, us-passport, schengen-visa, china-visa, india-visa, canada-visa, france-passport, and germany-visa. That page is a sample. It is not the list on your account, and some rows repeat one code string beside two English descriptions. uk-passport and uk-passport2 are both listed, and the reference says those names are not aliases.

Two endpoints on the Passport Photo API are the contract. POST /v2/listIdPhotoSpecCode returns specCode and specCodeName. POST /v2/getIdPhotoSpec returns pixel size, physical size, DPI, background, head height, expression, color, glasses, and recency, when the specification publishes them.

curl -sS -X POST "https://api-us.idphotoapp.com/v2/getIdPhotoSpec" \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "YOUR_API_KEY",
    "apiSecret": "YOUR_API_SECRET",
    "specCode": "us-passport"
  }'

The published us-passport example below is specific enough to drive a capture screen. Call the endpoint on your account before you render it, and read us-visa as its own code.

FieldExample value for us-passport
photoSize2 x 2 in
photoPixel600 x 600 px
photoDpi300 DPI
backgroundColor#FFFFFF (white)
headHeight1 - 1 3/8
eyeToBottom1 1/8 - 1 3/8
expressionNEUTRAL
glassesNOT_ALLOWED
colorIN_COLOR
recency6 months

The same example includes eyesAndEars VISIBLE_NO_HIDE. Those fields line up with the photo rules the US Department of State publishes for passport photos, including the instruction not to upload a photo created or edited with artificial intelligence or other digital tools. Cache the payload with the fetch time, and refresh it when you add a destination or when support adds a specification. A missing code returns ISSUE_PHOTO_SPEC_NOT_EXIST. Tell the traveler the photo could not be prepared, and alert an operator. The issue code reference says to query the list and submit a valid code.

A country and a document type pick the code

The traveler answers two questions: which country, and which document. Your product map turns that pair into one specCode. The API does not accept a country name.

A short-stay Schengen visa is often schengen-visa, even when the main destination is France, Germany, Spain, or Italy. A French passport is france-passport. germany-visa, spain-visa, and italy-passport are separate sample rows. Lock the code you fetched for that form. schengen-visa is the wrong file for a national passport, and us-passport is the wrong file for a US visa. Mixed appointments still use one code per request, as the batch ID photo page describes.

SKU you sellCode to confirm on the account
Schengen short-stay visaschengen-visa
French passportfrance-passport
US visaus-visa
US passportus-passport
UK online passportuk-passport or uk-digital-passport

Store the SKU id, the specCode, and the date you last compared getIdPhotoSpec with the capture screen. Review the screen if size, background, glasses, or recency change. us-greencard, us-ead, and us-dvlottery are separate rows when you sell them.

Show size, background, glasses, and recency from getIdPhotoSpec. The reference sample for schengen-visa is 413 × 531 px at 300 DPI, a 35 × 45 mm print, which is the size widely published for a Schengen visa photograph. Add a consulate sentence only when that consulate publishes one. For china-visa, india-visa, canada-visa, japan-visa, and australia-visa, use the millimetre size the detail endpoint returns.

What the capture screen should say

Build the checklist from the spec you fetched, plus the common mistakes guide:

Ask for a new photo when the problem is expression, glasses, or pose. makeIdPhoto already crops, sizes, and applies the specification background. Rewriting the face is the wrong tool for a US or UK passport, and the wrong default for a visa. The fix passport photo page is where a corrected portrait is allowed, such as a badge whose policy permits it.

One original portrait, one specification, one call

POST /v2/makeIdPhoto takes one imageBase64 and one specCode. Two applicants are two calls. A US visa photo and a Schengen visa photo from one sitting are two calls. Send the original capture to each one. The first JPEG is already cropped, and feeding it into the second country drops the margin the second spec needs. outputFormat defaults to S3_URL. IMAGE_BASE64 returns idPhotoImageBase64 when the file should stay in your storage. A data-URI prefix is optional on this endpoint.

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": "schengen-visa",
    "outputFormat": "IMAGE_BASE64"
  }'

Hosts are https://api-us.idphotoapp.com and https://api-eu.idphotoapp.com. Stay on the account’s region for the preview and the final file. The sample Python code reads the key and secret from the environment and uses a 120-second timeout. The data privacy policy covers encrypted transmission, temporary URLs kept from 2 hours to 14 days, and Base64 when the service should not store the image. Do not log the secret or the portrait.

The response carries photoUuid, specCode, pixel size, photoDpi, issues, and a URL or Base64. The schengen-visa sample is 413 × 531 px at 300 DPI. When fileSize is present, compare it with the form’s upload limit in your own code. An empty issues array means those checks reported no listed problem. A consulate or passport office still reviews the picture.

{
  "photoUuid": "example-photo-uuid",
  "waterMark": false,
  "specCode": "schengen-visa",
  "widthPx": 413,
  "heightPx": 531,
  "photoDpi": 300,
  "issues": []
}

Store photoUuid, the spec code, the issue list, and the application id. Copy URL output into your own storage inside the temporary window. A lost photoUuid cannot be exchanged for the clean file.

Preview when the traveler pays, direct when the file is already theirs

A consumer travel app should show the crop before payment. That is the same pair of calls as in the capture article:

  1. POST /v2/makeIdPhotoWatermark with the original portrait and the spec code. Optional watermarkText accepts only Preview or Aperçu, case-insensitively. The response has waterMark true and a photoUuid.
  2. After the traveler confirms, POST /v2/getIdPhotoNoWatermark with that photoUuid. The final response has waterMark false. Both calls use the same regional host.

An agency tool that stores the JPEG as soon as the checks are clear calls makeIdPhoto directly. Use one mode per photo.

For paper, add photoSheet.sheetSizes on the direct call or on getIdPhotoNoWatermark. Each entry is width*height in pixels, the example is 1800*1200, and the limit is 10 sizes. Download each URL promptly. The sheet repeats the portrait. It is not postage. Confirm mailing with support before you sell it. See the print and mailing page.

Turn issue codes into one sentence for that document

Show the traveler one instruction. Keep the raw code in your log. These are the codes that show up on a phone capture for a visa:

issueSensitivityOverride accepts VERY_LOW through VERY_HIGH. Higher is stricter, and it changes detection only. Leave it off for a government visa unless you have tested that camera.

Treat HTTP failures separately from issue codes: credentials, JSON, Base64, an unknown spec, processing, or a timeout. A timeout is not proof the photo was skipped, so skip the automatic retry until you know whether a result exists. Key the job by application id, spec code, and a hash of the source bytes. A morning of appointments is the same call in your own queue. Read makeIdPhotoApiRemaining from POST /v2/queryAccountStatus first. Figures in the docs are an example payload, not a plan size, and there is no batch-status webhook. Cap concurrency to the remaining quota.

Background removal is a preview, not the visa file

The specification already carries the background color, and makeIdPhoto returns the finished JPEG. Call background removal only for a transparent preview: POST /v2/removeBackground, or POST /v2/removeBackgroundFast on the capture screen. The request needs a data-URI prefix, outputFormat PNG or JPEG, and outputType IMAGE_BASE64. JPEG cannot keep transparency. Send the original portrait into makeIdPhoto.

Photo enhancement (POST /v2/photoEnhance) and shadow removal (POST /v2/removeShadow) can help a soft capture. enableFaceEnhance defaults to false because it can change small details. Neither call decides visa compliance. To compare the new photo with a passport biographical image, POST /v2/faceMatch on the Face Match API returns isMatch and similarity. Run issue codes first. The score is not a legal identity decision. Liveness and document OCR are outside that reference. See biometric verification for where the comparison sits.

A UK passport application is a photo code, not a visa JPEG

A UK online passport SKU returns a photo code, idPhotoCode, shaped like idfoto.net/P5E9E47P. The applicant enters it on GOV.UK. HM Passport Office retrieves the JPEG and checks it. The Passport Photo Code API returns the field for uk-passport and uk-digital-passport. Photos are checked against published GOV.UK photo rules, and the code is usable on the HM Passport Office online application because the applicant enters it there. A code is not an acceptance decision, and this service is not an HM Passport Office product.

That reference describes uk-passport as the standard 35 × 45 mm photo and uk-digital-passport as an alternative with an under-11 note. Confirm the SKU with getIdPhotoSpec. uk-passport and uk-passport2 are not aliases, and uk-driverlicense is a driving-licence photo with photo-code support marked optional. Direct mode returns the code with the JPEG. Watermark mode returns it on getIdPhotoNoWatermark, after payment. Codes stay retrievable for 21 days, which is our hosting period. GOV.UK expects the photograph to have been taken in the last month, and digital photos must be unedited. Read the UK passport photo code API page and the studio and pharmacy workflow. If a UK visa SKU is missing from the spec list, ask support to add it. Sending uk-passport and a photo code does not make the sale a visa photo.

A sequence you can ship

  1. Store the key and secret on the server, and note the US or EU host.
  2. Cache getIdPhotoSpec for every SKU, and bind that SKU to one specCode.
  3. Show that spec’s checklist and accept one original color portrait.
  4. Travel apps call makeIdPhotoWatermark, then getIdPhotoNoWatermark after confirmation. Agency tools call makeIdPhoto.
  5. Map a non-empty issues array to one retake. Keep ISSUE_PHOTO_SPEC_NOT_EXIST for the operator.
  6. Save photoUuid and copy the image into your storage. For a second document, call again with the original portrait.
  7. For a UK online passport, show idPhotoCode, the 21-day retrieval window, and the fact that HM Passport Office still checks the photo.
  8. Read queryAccountStatus before a batch, and cap workers to the remaining quota.

Keep POST /api/generate-portrait out of this flow. The AI headshot API makes directory portraits. It does not make a document photo.

Pitfalls that show up in agency integrations

FAQ

How do I find the visa photo size for a country?

Call POST /v2/getIdPhotoSpec and display photoSize, photoPixel, background, glasses, expression, and recency. Confirm the code with POST /v2/listIdPhotoSpecCode first.

Can one capture satisfy two visas?

Use it as the source for two calls and two spec codes. Send the original each time. The finished JPEG is already cropped.

Is schengen-visa the right code for every European document?

It is the sample code for a Schengen visa photo. france-passport, germany-visa, spain-visa, and italy-passport are different codes. Bind the SKU to the code you verified.

Does an empty issues array mean the visa will be accepted?

It means those checks reported no listed problem. The consulate still reviews the photo. A UK photo code meets GOV.UK photo rules and is usable on the HM Passport Office online application. It is not an acceptance decision.

Should I remove the background first?

Only for a transparent preview. POST /v2/makeIdPhoto applies the specification background and returns the finished file.

Where should the API key live?

On your server. The app uploads the portrait to you. Call the account’s US or EU host for both steps of a watermarked flow, and keep the secret and the Base64 image out of the client and the logs.