ID PhotoREST · JSONOpenAPI 3.1

SVOYAGER ID Photo API

Convierte cualquier foto en una foto válida para documento de identidad, pasaporte o visado.

Resumen

Qué hace

La API ID Photo API de SVOYAGER convierte un retrato normal en una foto de documento que cumple con los requisitos. ID Photo es un único producto: el pasaporte, el visado, el permiso de residencia y el DNI se representan como especificaciones de documentos, no como productos separados. Se sube una foto, se genera una vista previa con marca de agua según una especificación y, a continuación, se finaliza el proceso para obtener el resultado sin marca de agua.

Vista previa → flujo de trabajo final

  1. 1Sube una foto. Crea un destino de carga y envía los bytes de la imagen a dicho destino.
  2. 2Crear una sesión. Genera una vista previa con marca de agua según una especificación. Revisa los problemas detectados.
  3. 3Finalizar. Convierte la sesión revisada en un pedido y recibe el archivo final sin marca de agua.

Guía de inicio rápido

Cada solicitud se autentica con una clave secreta Bearer. Empieza en modo de prueba:

curl
# List specifications to find a spec_id
curl -G "https://partner.svoyager.com/v1/photo-specifications" \
  -H "Authorization: Bearer svoy_sk_test_YOUR_KEY" \
  --data-urlencode "country=US"

URL base y entornos

Todos los puntos finales se sirven bajo una única URL base:

Base URL
https://partner.svoyager.com/v1

No hay ninguna ruta ni parámetro de entorno. El hecho de que una solicitud se ejecute en entorno de prueba o en producción viene determinado exclusivamente por el prefijo de tu clave API (svoy_sk_test_… frente a svoy_sk_live_…). Las respuestas reflejan esto como «livemode».

Autenticación

Claves de API

Autentifica cada solicitud con un encabezado «Authorization» que contenga tu clave secreta. Las claves se crean y se renuevan en el Centro de socios.

Header
Authorization: Bearer svoy_sk_test_R2p9Kx7YOURKEYHERExxxxxxx

El prefijo indica el entorno: svoy_sk_test_… para el entorno de prueba, svoy_sk_live_… para el entorno de producción. Una clave de prueba nunca puede actuar sobre datos de producción (y viceversa); si no coinciden, se devuelve el código de estado 401 «wrong_environment».

Ámbitos

Las claves conllevan ámbitos explícitos de privilegios mínimos. Una solicitud que no incluya el ámbito requerido devuelve el código de estado 403 (insufficient_scope).

ÁmbitoConcesiones
photo.specs.readList and retrieve photo specifications.
photo.sessions.readRetrieve sessions and their previews.
photo.sessions.writeCreate uploads and photo sessions (previews).
photo.finalize.writeFinalize a session into a no-watermark order.
photo.orders.readRetrieve orders and download finals.

Mantener las claves a salvo

Las claves secretas son exclusivamente de servidor a servidor. Nunca incluyas una clave secreta en el código de un navegador o de un dispositivo móvil, en un repositorio público ni en un paquete del lado del cliente. Si se filtra una clave, cámbiala inmediatamente en el Partner Center.

API principal

Puntos finales

Los campos obligatorios están marcados con *. Los ejemplos utilizan credenciales de lugar de retención; nunca claves reales.

POST/v1/uploads

Upload a photo

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.

alcance photo.sessions.write
Solicitud
Cuerpo (application/json)
CampoTipoDescripción
content_type*stringMIME type of the image.image/jpegimage/pngimage/webpimage/heic
  • `upload_url` is single-use and expires; upload promptly and do not modify the URL.
Ejemplo de solicitud
curl
# 1) Create the upload target
curl -X POST "https://partner.svoyager.com/v1/uploads" \
  -H "Authorization: Bearer svoy_sk_test_R2p9Kx7YOURKEYHERExxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"content_type":"image/jpeg"}'

# 2) PUT the bytes to the returned upload_url (exactly as returned)
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: image/jpeg" \
  --data-binary @photo.jpg
Respuesta · 201
201 · application/json
{
  "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"
}
Errores
EstadoCódigoCuando
400missing_content_type`content_type` was not provided.
415unsupported_formatThe content type is not an accepted image format.
503temporarily_unavailableUploads are temporarily unavailable.
502upload_init_failedThe upload could not be initialised — retry shortly.

Además de los errores estándar de autenticación, permisos y límite de frecuencia; véase Errores y reintentos.

POST/v1/photo-sessions

Create a photo session

Generate a watermarked preview from an upload against a specification. Spends one `preview` unit of your plan. Review `issues` before finalizing.

alcance photo.sessions.write Se requiere Idempotency-Key
Solicitud
Cuerpo (application/json)
CampoTipoDescripción
upload_ref*stringThe `upload_ref` from Upload a photo.
spec_id*stringThe `photo_specification` id (`spc_…`) to render against.
Ejemplo de solicitud
curl
curl -X POST "https://partner.svoyager.com/v1/photo-sessions" \
  -H "Authorization: Bearer svoy_sk_test_R2p9Kx7YOURKEYHERExxxxxxx" \
  -H "Idempotency-Key: a7f3c9e1-2b4d-4c8a-9f10-3e5d6b7a8c9d" \
  -H "Content-Type: application/json" \
  -d '{"upload_ref":"up_ref_tXk3W2b8Qe7Ra1Nc0","spec_id":"spc_9wTv2c1Kd8Qe"}'
Respuesta · 201
201 · application/json
{
  "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"
}
Errores
EstadoCódigoCuando
400missing_idempotency_keyThe `Idempotency-Key` header is missing.
400missing_upload_ref`upload_ref` is missing.
400missing_spec_id`spec_id` is missing.
400invalid_upload_refThe referenced upload could not be read.
413file_too_largeThe uploaded file exceeds 10 MB.
415unsupported_formatThe uploaded file is not an accepted image format.
404spec_not_foundNo active specification matches `spec_id`.
402no_active_planNo active plan is assigned for this environment.
402quota_exceededIncluded preview quota for the period is exhausted.
402plan_inactiveThe plan is not active for this environment.
409idempotency_key_reuseThe key was reused with a different body.
409request_in_progressA request with this key is still processing.
422unprocessable_imageThe image could not be processed.
502provider_errorThe preview could not be generated upstream — retry shortly.
503provider_busyThe processing service is busy — retry shortly.

Además de los errores estándar de autenticación, permisos y límite de frecuencia; véase Errores y reintentos.

GET/v1/photo-sessions/{id}

Retrieve a photo session

Fetch a session by id, including its current status, `preview_url`, and any `issues`.

alcance photo.sessions.read
Solicitud
Parámetros de ruta
CampoTipoDescripción
id*stringSession id.
Ejemplo de solicitud
curl
curl "https://partner.svoyager.com/v1/photo-sessions/3f9c1e77-2b8a-4a1e-9d2c-6b5a4c3d2e10" \
  -H "Authorization: Bearer svoy_sk_test_R2p9Kx7YOURKEYHERExxxxxxx"
Respuesta · 200
200 · application/json
{
  "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"
}
Errores
EstadoCódigoCuando
404session_not_foundNo session matches the id for this account/environment.

Además de los errores estándar de autenticación, permisos y límite de frecuencia; véase Errores y reintentos.

GET/v1/photo-sessions/{id}/preview

Download the preview image

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.

alcance photo.sessions.readDevuelve los bytes de la imagen
Solicitud
Parámetros de ruta
CampoTipoDescripción
id*stringSession id.
  • Returns raw `image/*` bytes on success (not JSON).
Ejemplo de solicitud
curl
curl "https://partner.svoyager.com/v1/photo-sessions/3f9c1e77-2b8a-4a1e-9d2c-6b5a4c3d2e10/preview" \
  -H "Authorization: Bearer svoy_sk_test_R2p9Kx7YOURKEYHERExxxxxxx" \
  --output preview.jpg
Respuesta · 200

Si la operación se realiza con éxito, el punto final transmite los bytes de la imagen sin procesar (no en formato JSON). Guarda el cuerpo de la respuesta en un archivo.

Errores
EstadoCódigoCuando
404preview_not_foundThe session or its preview does not exist.

Además de los errores estándar de autenticación, permisos y límite de frecuencia; véase Errores y reintentos.

POST/v1/photo-sessions/{id}/finalize

Finalize a photo

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.

alcance photo.finalize.write Se requiere Idempotency-Key
Solicitud
Parámetros de ruta
CampoTipoDescripción
id*stringSession id to finalize.
Ejemplo de solicitud
curl
curl -X POST "https://partner.svoyager.com/v1/photo-sessions/3f9c1e77-2b8a-4a1e-9d2c-6b5a4c3d2e10/finalize" \
  -H "Authorization: Bearer svoy_sk_live_A8m4Qz1YOURKEYHERExxxxxxx" \
  -H "Idempotency-Key: a7f3c9e1-2b4d-4c8a-9f10-3e5d6b7a8c9d"
Respuesta · 201Returns 200 with the existing order if the session was already finalized (never double-charged).
201 · application/json
{
  "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"
}
Errores
EstadoCódigoCuando
400missing_idempotency_keyThe `Idempotency-Key` header is missing.
404session_not_foundNo session matches the id for this account/environment.
422session_not_finalizableThe session is not in a finalizable state.
402no_active_planNo active plan is assigned for this environment.
402quota_exceededIncluded final quota for the period is exhausted.
402plan_inactiveThe plan is not active for this environment.
409idempotency_key_reuseThe key was reused with a different request.
409request_in_progressA request with this key is still processing.
502provider_errorThe final could not be produced upstream — retry shortly.
503provider_busyThe processing service is busy — retry shortly.

Además de los errores estándar de autenticación, permisos y límite de frecuencia; véase Errores y reintentos.

GET/v1/orders/{id}

Retrieve an order

Fetch a finalized order by id, including its status and `final_url` once ready.

alcance photo.orders.read
Solicitud
Parámetros de ruta
CampoTipoDescripción
id*stringOrder id.
Ejemplo de solicitud
curl
curl "https://partner.svoyager.com/v1/orders/8a2d5b40-71c6-4f0e-b3a9-1e7c9d05f284" \
  -H "Authorization: Bearer svoy_sk_live_A8m4Qz1YOURKEYHERExxxxxxx"
Respuesta · 200
200 · application/json
{
  "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"
}
Errores
EstadoCódigoCuando
404order_not_foundNo order matches the id for this account/environment.

Además de los errores estándar de autenticación, permisos y límite de frecuencia; véase Errores y reintentos.

GET/v1/orders/{id}/final

Download the final image

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.

alcance photo.orders.readDevuelve los bytes de la imagen
Solicitud
Parámetros de ruta
CampoTipoDescripción
id*stringOrder id.
  • Returns raw `image/*` bytes on success (not JSON).
Ejemplo de solicitud
curl
curl "https://partner.svoyager.com/v1/orders/8a2d5b40-71c6-4f0e-b3a9-1e7c9d05f284/final" \
  -H "Authorization: Bearer svoy_sk_live_A8m4Qz1YOURKEYHERExxxxxxx" \
  --output final.jpg
Respuesta · 200

Si la operación se realiza con éxito, el punto final transmite los bytes de la imagen sin procesar (no en formato JSON). Guarda el cuerpo de la respuesta en un archivo.

Errores
EstadoCódigoCuando
404final_not_foundThe order or its final does not exist.

Además de los errores estándar de autenticación, permisos y límite de frecuencia; véase Errores y reintentos.

GET/v1/photo-specifications

List photo specifications

Return a cursor-paginated list of available photo specifications. Filter by country or document type to find the `spec_id` you need.

alcance photo.specs.read
Solicitud
Parámetros de consulta
CampoTipoDescripción
limitintegerPage size, 1–100 (default 20).
starting_afterstringA specification id (`spc_…`) to page after.
countrystringISO-3166 alpha-2 filter, e.g. `US`.
document_typestringFilter by document type, e.g. `passport`.
Ejemplo de solicitud
curl
curl -G "https://partner.svoyager.com/v1/photo-specifications" \
  -H "Authorization: Bearer svoy_sk_test_R2p9Kx7YOURKEYHERExxxxxxx" \
  --data-urlencode "country=US" \
  --data-urlencode "limit=20"
Respuesta · 200
200 · application/json
{
  "object": "list",
  "data": [
    {
      "object": "photo_specification",
      "id": "spc_9wTv2c1Kd8Qe",
      "name": "United States Passport"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
Errores

Este punto final solo devuelve los errores estándar que se indican a continuación.

Además de los errores estándar de autenticación, permisos y límite de frecuencia; véase Errores y reintentos.

GET/v1/photo-specifications/{id}

Retrieve a photo specification

Fetch a single specification by its stable `spec_id`, including its full requirements.

alcance photo.specs.read
Solicitud
Parámetros de ruta
CampoTipoDescripción
id*stringSpecification id (`spc_…`).
Ejemplo de solicitud
curl
curl "https://partner.svoyager.com/v1/photo-specifications/spc_9wTv2c1Kd8Qe" \
  -H "Authorization: Bearer svoy_sk_test_R2p9Kx7YOURKEYHERExxxxxxx"
Respuesta · 200
200 · application/json
{
  "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"
}
Errores
EstadoCódigoCuando
404spec_not_foundNo active specification matches the id.

Además de los errores estándar de autenticación, permisos y límite de frecuencia; véase Errores y reintentos.

Envía un encabezado Idempotency-Key (un valor único, por ejemplo, un UUID) para que una solicitud reintentada nunca se cobre o se procese dos veces. Es obligatorio en:

  • POST /v1/photo-sessions
  • POST /v1/photo-sessions/{id}/finalize
  • Misma clave + mismo cuerpo → se reproduce el resultado original (sin segundo cargo, sin segunda representación).
  • La misma clave + un cuerpo diferente → 409 idempotency_key_reuse.
  • Un error que admite reintentos te permite volver a intentarlo con la misma clave, el mismo cuerpo y el mismo `upload_ref`.
  • Las solicitudes de finalización simultáneas de una misma sesión nunca pueden crear ni cobrar dos pedidos.

Una sesión pasa por distintos estados de vista previa; un pedido, por distintos estados de finalización.

Estado de la sesión
  • preview_readySe ha generado una vista previa, sin problemas.
  • preview_has_issuesvista previa generada con incidencias.
  • preview_failedNo se ha podido generar la vista previa.
  • finalizedla sesión se ha finalizado.
Estado del pedido
  • final_readyLa versión final ya está disponible.
  • processingSe está preparando la versión final.
  • failedError en la finalización.

El entorno viene determinado por el prefijo de tu clave; los clientes nunca pueden modificarlo. El modo de prueba muestra la vista previa real con marca de agua para que puedas practicar el flujo real, pero emula el resultado final, por lo que no se utiliza la cuota en vivo ni el renderizado de producción.

AspectPruebaEn directo
livemodefalsetrue
Vista previaReal, con marca de aguaReal, con marca de agua
FinalSandbox emulado a partir de la vista previaReal, sin marca de agua
sandbox_emulatedtruefalse
watermarkedtruefalse
Cuota consumidaSolo cuota de pruebaSolo cuota en tiempo real

Tu plan incluye un número determinado de vistas previas y versiones definitivas por periodo, que se cuentan por separado. Crear una sesión consume una vista previa; finalizarla consume una versión definitiva. La cuota se reserva de forma atómica antes del procesamiento.

  • Cuando se agota la cuota de vista previa o la cuota final incluida, la solicitud devuelve el código 402 «quota_exceeded».
  • El código 402 supone una interrupción definitiva: los reintentos no tendrán éxito hasta el siguiente periodo o hasta que se produzca un cambio de plan.
  • Los límites de cuota de prueba y de producción son totalmente independientes.

Cada error utiliza un sobre. El request_id también aparece en el encabezado de respuesta X-Request-Id; inclúyelo en las solicitudes de asistencia.

Error envelope
{
  "error": {
    "type": "invalid_request_error",
    "code": "quota_exceeded",
    "message": "Your included final quota for this period is exhausted.",
    "request_id": "req_9wTv2c1Kd8QeR7"
  }
}

Errores estándar (todos los puntos finales)

EstadoCódigoCuando
401invalid_api_keyMissing, malformed, or unknown API key.
401revoked_api_keyThe key was revoked.
401expired_api_keyThe key passed its rotation grace period.
401wrong_environmentA test key was used on live traffic (or vice versa).
403client_disabledThe API client is disabled.
403api_access_revokedAPI access for the account is not active.
403insufficient_scopeThe key lacks the required scope for this endpoint.
429rate_limitedPer-key rate limit exceeded. Honour `Retry-After`.

El código 422 solo se devuelve en caso de un problema confirmado con la imagen. El código 402 significa que se ha agotado la cuota. El código 409 indica un conflicto de idempotencia o de recursos.

El código 429 significa que se ha alcanzado el límite de frecuencia por clave; respeta el encabezado «Retry-After». En el caso de los códigos 502/503 y otros 5xx, vuelve a intentarlo con un tiempo de espera y la misma «Idempotency-Key».

Una vista previa puede devolver cero o más incidencias, cada una de ellas compuesta por un código estable y un mensaje. Muéstralas al usuario final para que pueda volver a hacer la foto. Una señal de origen no reconocida se degrada a «other».

CódigoMensaje
face_not_foundNo face was detected in the photo.
uneven_lightingLighting on the face is uneven.
poor_brightnessFace brightness is too dark, too bright, or the photo is low quality.
low_sharpnessThe photo is blurry or not sharp enough.
eyeglasses_not_allowedEyeglasses are not allowed.
sunglasses_not_allowedSunglasses are not allowed.
headwear_not_allowedHats or head coverings are not allowed.
face_mask_not_allowedA face mask is not allowed.
face_covering_foundA face covering was detected.
expression_not_neutralThe expression is not neutral.
crop_bottomNot enough space is visible below the shoulders.
crop_leftNot enough of the left shoulder is visible.
crop_rightNot enough of the right shoulder is visible.
head_turnedThe head is turned too far to the side.
head_tiltedThe head is tilted too far up or down.
not_in_colorThe photo must be in color.
otherThe photo did not meet a requirement.
  • Las vistas previas y las versiones definitivas solo se sirven desde URL autenticadas y alojadas por SVOYAGER. El acceso requiere tu clave API y el ámbito correcto; el almacenamiento subyacente nunca se expone públicamente.
  • Las imágenes subidas son privadas y están limitadas a tu cuenta y entorno; los destinos de subida son de corta duración y de un solo uso.
  • Las fotos de los documentos se procesan para generar el resultado y no se comparten entre cuentas.

Consulte las condiciones de SVOYAGER relativas al tratamiento, la conservación y la supresión de datos:Política de privacidad ·Acuerdo y condiciones para socios