{"openapi":"3.1.0","info":{"title":"SVOYAGER ID Photo API","version":"v1 (2026-07-24)","summary":"Turn any photo into a compliant ID / passport / visa photo.","description":"Programmatic access to the SVOYAGER ID Photo API.\n\nID Photo is a single product: passport, visa, residence-permit and national-ID are represented as document *specifications*, not separate products.\n\nThe environment (test or live) is determined by your API key prefix, never by a request parameter.","contact":{"name":"SVOYAGER Partnerships","email":"partnerships@svoyager.com"}},"servers":[{"url":"https://partner.svoyager.com/v1","description":"Production"}],"tags":[{"name":"Core API","description":"Uploads, sessions, finalization, orders and specifications."}],"x-scopes":{"photo.specs.read":"List and retrieve photo specifications.","photo.sessions.read":"Retrieve sessions and their previews.","photo.sessions.write":"Create uploads and photo sessions (previews).","photo.finalize.write":"Finalize a session into a no-watermark order.","photo.orders.read":"Retrieve orders and download finals."},"paths":{"/v1/photo-specifications":{"get":{"operationId":"listPhotoSpecifications","summary":"List photo specifications","description":"Return a cursor-paginated list of available photo specifications. Filter by country or document type to find the `spec_id` you need.","tags":["Core API"],"security":[{"bearerAuth":[]}],"x-scope":"photo.specs.read","parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1–100 (default 20).","schema":{"type":"integer","description":"Page size, 1–100 (default 20)."},"example":"20"},{"name":"starting_after","in":"query","required":false,"description":"A specification id (`spc_…`) to page after.","schema":{"type":"string","description":"A specification id (`spc_…`) to page after."},"example":"spc_9wTv2c1Kd8Qe"},{"name":"country","in":"query","required":false,"description":"ISO-3166 alpha-2 filter, e.g. `US`.","schema":{"type":"string","description":"ISO-3166 alpha-2 filter, e.g. `US`."},"example":"US"},{"name":"document_type","in":"query","required":false,"description":"Filter by document type, e.g. `passport`.","schema":{"type":"string","description":"Filter by document type, e.g. `passport`."},"example":"passport"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/list"}}}},"401":{"description":"`invalid_api_key` — Missing, malformed, or unknown API key.\n`revoked_api_key` — The key was revoked.\n`expired_api_key` — The key passed its rotation grace period.\n`wrong_environment` — A test key was used on live traffic (or vice versa).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"403":{"description":"`client_disabled` — The API client is disabled.\n`api_access_revoked` — API access for the account is not active.\n`insufficient_scope` — The key lacks the required scope for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"429":{"description":"`rate_limited` — Per-key rate limit exceeded. Honour `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/v1/photo-specifications/{id}":{"get":{"operationId":"getPhotoSpecification","summary":"Retrieve a photo specification","description":"Fetch a single specification by its stable `spec_id`, including its full requirements.","tags":["Core API"],"security":[{"bearerAuth":[]}],"x-scope":"photo.specs.read","parameters":[{"name":"id","in":"path","required":true,"description":"Specification id (`spc_…`).","schema":{"type":"string","description":"Specification id (`spc_…`)."},"example":"spc_9wTv2c1Kd8Qe"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/photo_specification"}}}},"401":{"description":"`invalid_api_key` — Missing, malformed, or unknown API key.\n`revoked_api_key` — The key was revoked.\n`expired_api_key` — The key passed its rotation grace period.\n`wrong_environment` — A test key was used on live traffic (or vice versa).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"403":{"description":"`client_disabled` — The API client is disabled.\n`api_access_revoked` — API access for the account is not active.\n`insufficient_scope` — The key lacks the required scope for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"`spec_not_found` — No active specification matches the id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"429":{"description":"`rate_limited` — Per-key rate limit exceeded. Honour `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/v1/uploads":{"post":{"operationId":"createUpload","summary":"Upload a photo","description":"Create a short-lived presigned upload target, then PUT the raw image bytes straight to `upload_url`. This bypasses request-body size limits (product cap 10 MB). No quota is spent.","tags":["Core API"],"security":[{"bearerAuth":[]}],"x-scope":"photo.sessions.write","responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/upload"}}}},"400":{"description":"`missing_content_type` — `content_type` was not provided.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"401":{"description":"`invalid_api_key` — Missing, malformed, or unknown API key.\n`revoked_api_key` — The key was revoked.\n`expired_api_key` — The key passed its rotation grace period.\n`wrong_environment` — A test key was used on live traffic (or vice versa).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"403":{"description":"`client_disabled` — The API client is disabled.\n`api_access_revoked` — API access for the account is not active.\n`insufficient_scope` — The key lacks the required scope for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"415":{"description":"`unsupported_format` — The content type is not an accepted image format.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"429":{"description":"`rate_limited` — Per-key rate limit exceeded. Honour `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"502":{"description":"`upload_init_failed` — The upload could not be initialised — retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"503":{"description":"`temporarily_unavailable` — Uploads are temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["content_type"],"properties":{"content_type":{"type":"string","enum":["image/jpeg","image/png","image/webp","image/heic"],"description":"MIME type of the image."}}},"example":{"content_type":"image/jpeg"}}}}}},"/v1/photo-sessions":{"post":{"operationId":"createPhotoSession","summary":"Create a photo session","description":"Generate a watermarked preview from an upload against a specification. Spends one `preview` unit of your plan. Review `issues` before finalizing.","tags":["Core API"],"security":[{"bearerAuth":[]}],"x-scope":"photo.sessions.write","x-idempotent":true,"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"A unique key (e.g. a UUID) so retries are safe. Same key + same body replays the original result; same key + different body → 409.","schema":{"type":"string","description":"A unique key (e.g. a UUID) so retries are safe. Same key + same body replays the original result; same key + different body → 409."},"example":"a7f3c9e1-2b4d-4c8a-9f10-3e5d6b7a8c9d"}],"responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/photo_session"}}}},"400":{"description":"`missing_idempotency_key` — The `Idempotency-Key` header is missing.\n`missing_upload_ref` — `upload_ref` is missing.\n`missing_spec_id` — `spec_id` is missing.\n`invalid_upload_ref` — The referenced upload could not be read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"401":{"description":"`invalid_api_key` — Missing, malformed, or unknown API key.\n`revoked_api_key` — The key was revoked.\n`expired_api_key` — The key passed its rotation grace period.\n`wrong_environment` — A test key was used on live traffic (or vice versa).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"402":{"description":"`no_active_plan` — No active plan is assigned for this environment.\n`quota_exceeded` — Included preview quota for the period is exhausted.\n`plan_inactive` — The plan is not active for this environment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"403":{"description":"`client_disabled` — The API client is disabled.\n`api_access_revoked` — API access for the account is not active.\n`insufficient_scope` — The key lacks the required scope for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"`spec_not_found` — No active specification matches `spec_id`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"409":{"description":"`idempotency_key_reuse` — The key was reused with a different body.\n`request_in_progress` — A request with this key is still processing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"413":{"description":"`file_too_large` — The uploaded file exceeds 10 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"415":{"description":"`unsupported_format` — The uploaded file is not an accepted image format.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"`unprocessable_image` — The image could not be processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"429":{"description":"`rate_limited` — Per-key rate limit exceeded. Honour `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"502":{"description":"`provider_error` — The preview could not be generated upstream — retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"503":{"description":"`provider_busy` — The processing service is busy — retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["upload_ref","spec_id"],"properties":{"upload_ref":{"type":"string","description":"The `upload_ref` from Upload a photo."},"spec_id":{"type":"string","description":"The `photo_specification` id (`spc_…`) to render against."}}},"example":{"upload_ref":"up_ref_tXk3W2b8Qe7Ra1Nc0","spec_id":"spc_9wTv2c1Kd8Qe"}}}}}},"/v1/photo-sessions/{id}":{"get":{"operationId":"getPhotoSession","summary":"Retrieve a photo session","description":"Fetch a session by id, including its current status, `preview_url`, and any `issues`.","tags":["Core API"],"security":[{"bearerAuth":[]}],"x-scope":"photo.sessions.read","parameters":[{"name":"id","in":"path","required":true,"description":"Session id.","schema":{"type":"string","description":"Session id."},"example":"3f9c1e77-2b8a-4a1e-9d2c-6b5a4c3d2e10"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/photo_session"}}}},"401":{"description":"`invalid_api_key` — Missing, malformed, or unknown API key.\n`revoked_api_key` — The key was revoked.\n`expired_api_key` — The key passed its rotation grace period.\n`wrong_environment` — A test key was used on live traffic (or vice versa).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"403":{"description":"`client_disabled` — The API client is disabled.\n`api_access_revoked` — API access for the account is not active.\n`insufficient_scope` — The key lacks the required scope for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"`session_not_found` — No session matches the id for this account/environment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"429":{"description":"`rate_limited` — Per-key rate limit exceeded. Honour `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/v1/photo-sessions/{id}/preview":{"get":{"operationId":"getSessionPreview","summary":"Download the preview image","description":"Stream the watermarked preview image bytes for a session (SVOYAGER-hosted; the upstream URL is never exposed). This is the resource `preview_url` points to.","tags":["Core API"],"security":[{"bearerAuth":[]}],"x-scope":"photo.sessions.read","parameters":[{"name":"id","in":"path","required":true,"description":"Session id.","schema":{"type":"string","description":"Session id."},"example":"3f9c1e77-2b8a-4a1e-9d2c-6b5a4c3d2e10"}],"responses":{"200":{"description":"The image bytes.","content":{"image/*":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"`invalid_api_key` — Missing, malformed, or unknown API key.\n`revoked_api_key` — The key was revoked.\n`expired_api_key` — The key passed its rotation grace period.\n`wrong_environment` — A test key was used on live traffic (or vice versa).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"403":{"description":"`client_disabled` — The API client is disabled.\n`api_access_revoked` — API access for the account is not active.\n`insufficient_scope` — The key lacks the required scope for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"`preview_not_found` — The session or its preview does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"429":{"description":"`rate_limited` — Per-key rate limit exceeded. Honour `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/v1/photo-sessions/{id}/finalize":{"post":{"operationId":"finalizePhotoSession","summary":"Finalize a photo","description":"Turn a reviewed session into a deliverable order. In live mode this produces the no-watermark final and spends one `final` unit; in test mode it emulates the final from the preview.","tags":["Core API"],"security":[{"bearerAuth":[]}],"x-scope":"photo.finalize.write","x-idempotent":true,"parameters":[{"name":"id","in":"path","required":true,"description":"Session id to finalize.","schema":{"type":"string","description":"Session id to finalize."},"example":"3f9c1e77-2b8a-4a1e-9d2c-6b5a4c3d2e10"},{"name":"Idempotency-Key","in":"header","required":true,"description":"A unique key (e.g. a UUID) so retries are safe. Same key + same body replays the original result; same key + different body → 409.","schema":{"type":"string","description":"A unique key (e.g. a UUID) so retries are safe. Same key + same body replays the original result; same key + different body → 409."},"example":"a7f3c9e1-2b4d-4c8a-9f10-3e5d6b7a8c9d"}],"responses":{"201":{"description":"Success. Returns 200 with the existing order if the session was already finalized (never double-charged).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/photo_order"}}}},"400":{"description":"`missing_idempotency_key` — The `Idempotency-Key` header is missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"401":{"description":"`invalid_api_key` — Missing, malformed, or unknown API key.\n`revoked_api_key` — The key was revoked.\n`expired_api_key` — The key passed its rotation grace period.\n`wrong_environment` — A test key was used on live traffic (or vice versa).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"402":{"description":"`no_active_plan` — No active plan is assigned for this environment.\n`quota_exceeded` — Included final quota for the period is exhausted.\n`plan_inactive` — The plan is not active for this environment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"403":{"description":"`client_disabled` — The API client is disabled.\n`api_access_revoked` — API access for the account is not active.\n`insufficient_scope` — The key lacks the required scope for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"`session_not_found` — No session matches the id for this account/environment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"409":{"description":"`idempotency_key_reuse` — The key was reused with a different request.\n`request_in_progress` — A request with this key is still processing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"`session_not_finalizable` — The session is not in a finalizable state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"429":{"description":"`rate_limited` — Per-key rate limit exceeded. Honour `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"502":{"description":"`provider_error` — The final could not be produced upstream — retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"503":{"description":"`provider_busy` — The processing service is busy — retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/v1/orders/{id}":{"get":{"operationId":"getOrder","summary":"Retrieve an order","description":"Fetch a finalized order by id, including its status and `final_url` once ready.","tags":["Core API"],"security":[{"bearerAuth":[]}],"x-scope":"photo.orders.read","parameters":[{"name":"id","in":"path","required":true,"description":"Order id.","schema":{"type":"string","description":"Order id."},"example":"8a2d5b40-71c6-4f0e-b3a9-1e7c9d05f284"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/photo_order"}}}},"401":{"description":"`invalid_api_key` — Missing, malformed, or unknown API key.\n`revoked_api_key` — The key was revoked.\n`expired_api_key` — The key passed its rotation grace period.\n`wrong_environment` — A test key was used on live traffic (or vice versa).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"403":{"description":"`client_disabled` — The API client is disabled.\n`api_access_revoked` — API access for the account is not active.\n`insufficient_scope` — The key lacks the required scope for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"`order_not_found` — No order matches the id for this account/environment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"429":{"description":"`rate_limited` — Per-key rate limit exceeded. Honour `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/v1/orders/{id}/final":{"get":{"operationId":"getOrderFinal","summary":"Download the final image","description":"Stream the final image bytes for an order (SVOYAGER-hosted). In live mode this is the no-watermark deliverable; in test mode it is the sandbox-emulated copy. This is the resource `final_url` points to.","tags":["Core API"],"security":[{"bearerAuth":[]}],"x-scope":"photo.orders.read","parameters":[{"name":"id","in":"path","required":true,"description":"Order id.","schema":{"type":"string","description":"Order id."},"example":"8a2d5b40-71c6-4f0e-b3a9-1e7c9d05f284"}],"responses":{"200":{"description":"The image bytes.","content":{"image/*":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"`invalid_api_key` — Missing, malformed, or unknown API key.\n`revoked_api_key` — The key was revoked.\n`expired_api_key` — The key passed its rotation grace period.\n`wrong_environment` — A test key was used on live traffic (or vice versa).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"403":{"description":"`client_disabled` — The API client is disabled.\n`api_access_revoked` — API access for the account is not active.\n`insufficient_scope` — The key lacks the required scope for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"`final_not_found` — The order or its final does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"429":{"description":"`rate_limited` — Per-key rate limit exceeded. Honour `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Secret API key. `Authorization: Bearer svoy_sk_{test|live}_…`. The environment is derived from the prefix."}},"schemas":{"photo_specification":{"type":"object","title":"Photo specification","description":"A stable, government-aligned photo specification (dimensions, background, and requirements). ID Photo is one product; passport, visa, residence-permit and national-ID are represented here as `document_type` values, not separate products.","required":["object","id","name","country_code","document_type","physical_size","pixel_size","dpi","background","requirements","updated_at"],"properties":{"object":{"type":"string","description":"Always `photo_specification`."},"id":{"type":"string","description":"Stable specification id (`spc_…`). Use it as `spec_id` when creating a session."},"name":{"type":"string","description":"Human name, e.g. “United States Passport”."},"country_code":{"type":["string","null"],"description":"ISO-3166 alpha-2 country code, or null when not country-bound."},"document_type":{"type":"string","description":"Document category, e.g. `passport`, `visa`, `id_card`, `residence_permit`."},"physical_size":{"type":["object","null"],"additionalProperties":true,"description":"`{ width, height, unit }` — printed size (unit is `mm` or `in`)."},"pixel_size":{"type":["object","null"],"additionalProperties":true,"description":"`{ width, height }` — target pixel dimensions."},"dpi":{"type":["integer","null"],"description":"Print resolution when defined."},"background":{"type":["object","null"],"additionalProperties":true,"description":"`{ color, name }` — required background."},"requirements":{"type":"object","additionalProperties":true,"description":"Human-readable compliance rules (head height, expression, glasses, colour, …)."},"updated_at":{"type":"string","description":"ISO-8601 timestamp of the last change to this specification."}},"example":{"object":"photo_specification","id":"spc_9wTv2c1Kd8Qe","name":"United States Passport","country_code":"US","document_type":"passport","physical_size":{"width":51,"height":51,"unit":"mm"},"pixel_size":{"width":600,"height":600},"dpi":300,"background":{"color":"#FFFFFF","name":"white"},"requirements":{"head_height":"25–35 mm (1–1⅜ in)","eye_to_bottom":"28–35 mm (1⅛–1⅜ in)","recency_months":6,"expression":"neutral","color":true,"glasses":"not allowed","eyes_and_ears":"both eyes open"},"updated_at":"2026-07-01T12:00:00Z"}},"upload":{"type":"object","title":"Upload target","description":"A short-lived, presigned upload target. PUT the raw image bytes to `upload_url` exactly as returned, then pass `upload_ref` to Create a photo session.","required":["object","upload_url","upload_ref","max_bytes","expires_at"],"properties":{"object":{"type":"string","description":"Always `upload`."},"upload_url":{"type":"string","description":"Presigned PUT URL. Upload the bytes to this exact URL (do not add headers or modify it). Host shown is illustrative."},"upload_ref":{"type":"string","description":"Opaque reference to the uploaded image. Pass it as `upload_ref` when creating a session."},"max_bytes":{"type":"integer","description":"Maximum accepted upload size in bytes (10 MB)."},"expires_at":{"type":"string","description":"ISO-8601 time after which the upload target is no longer valid."}},"example":{"object":"upload","upload_url":"https://upload.svoyager.com/v1/EXAMPLE?signature=…","upload_ref":"up_ref_tXk3W2b8Qe7Ra1Nc0","max_bytes":10485760,"expires_at":"2026-07-24T18:20:00Z"}},"photo_session":{"type":"object","title":"Photo session","description":"A watermarked preview generated from an upload against a specification. Review the preview (and any `issues`) before finalizing to obtain the no-watermark image.","required":["object","id","livemode","status","spec_id","preview_url","watermarked","issues","created_at"],"properties":{"object":{"type":"string","description":"Always `photo_session`."},"id":{"type":"string","description":"Session id. Use it to retrieve the session or to finalize."},"livemode":{"type":"boolean","description":"`false` for test keys, `true` for live keys."},"status":{"type":"string","enum":["preview_ready","preview_has_issues","preview_failed","finalized"],"description":"Preview outcome / lifecycle state."},"spec_id":{"type":["string","null"],"description":"The `photo_specification` id used."},"preview_url":{"type":["string","null"],"description":"SVOYAGER-hosted, authenticated URL to the watermarked preview image."},"watermarked":{"type":"boolean","description":"Always `true` for a preview."},"issues":{"type":"array","items":{},"description":"Zero or more `{ code, message }` compliance issues detected in the preview."},"created_at":{"type":"string","description":"ISO-8601 creation time."}},"example":{"object":"photo_session","id":"3f9c1e77-2b8a-4a1e-9d2c-6b5a4c3d2e10","livemode":false,"status":"preview_ready","spec_id":"spc_9wTv2c1Kd8Qe","preview_url":"https://partner.svoyager.com/v1/photo-sessions/3f9c1e77-2b8a-4a1e-9d2c-6b5a4c3d2e10/preview","watermarked":true,"issues":[],"created_at":"2026-07-24T18:30:00Z"}},"photo_order":{"type":"object","title":"Photo order","description":"The result of finalizing a session: the deliverable ID photo. In live mode the final has no watermark; in test mode it is a sandbox-emulated (watermarked) copy of the preview.","required":["object","id","livemode","sandbox_emulated","status","session_id","spec_id","final_url","watermarked","created_at"],"properties":{"object":{"type":"string","description":"Always `photo_order`."},"id":{"type":"string","description":"Order id. Use it to retrieve the order or download the final."},"livemode":{"type":"boolean","description":"`false` for test keys, `true` for live keys."},"sandbox_emulated":{"type":"boolean","description":"`true` when the final was emulated from the preview in test mode (no real render)."},"status":{"type":"string","enum":["final_ready","processing","failed"],"description":"Finalization state."},"session_id":{"type":["string","null"],"description":"The session this order was finalized from."},"spec_id":{"type":["string","null"],"description":"The `photo_specification` id used."},"final_url":{"type":["string","null"],"description":"SVOYAGER-hosted, authenticated URL to the final image (null until `final_ready`)."},"watermarked":{"type":"boolean","description":"`false` for a live final; `true` for a test/sandbox final."},"created_at":{"type":"string","description":"ISO-8601 creation time."}},"example":{"object":"photo_order","id":"8a2d5b40-71c6-4f0e-b3a9-1e7c9d05f284","livemode":true,"sandbox_emulated":false,"status":"final_ready","session_id":"3f9c1e77-2b8a-4a1e-9d2c-6b5a4c3d2e10","spec_id":"spc_9wTv2c1Kd8Qe","final_url":"https://partner.svoyager.com/v1/orders/8a2d5b40-71c6-4f0e-b3a9-1e7c9d05f284/final","watermarked":false,"created_at":"2026-07-24T18:31:00Z"}},"list":{"type":"object","title":"List","description":"A cursor-paginated collection. Use `next_cursor` as `starting_after` to fetch the next page while `has_more` is true.","required":["object","data","has_more","next_cursor"],"properties":{"object":{"type":"string","description":"Always `list`."},"data":{"type":"array","items":{},"description":"The page of objects."},"has_more":{"type":"boolean","description":"Whether more objects exist after this page."},"next_cursor":{"type":["string","null"],"description":"Cursor for the next page (pass as `starting_after`)."}},"example":{"object":"list","data":[{"object":"photo_specification","id":"spc_9wTv2c1Kd8Qe","name":"United States Passport"}],"has_more":false,"next_cursor":null}},"error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["type","code","message","request_id"],"properties":{"type":{"type":"string","enum":["invalid_request_error","authentication_error","permission_error","rate_limit_error","api_error"]},"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"}}}},"example":{"error":{"type":"invalid_request_error","code":"quota_exceeded","message":"Your included final quota for this period is exhausted.","request_id":"req_9wTv2c1Kd8QeR7"}}}}},"security":[{"bearerAuth":[]}]}