ID PhotoREST · JSONOpenAPI 3.1

SVOYAGER ID Photo API

Trasforma qualsiasi foto in una foto conforme per carta d’identità, passaporto o visto.

Panoramica

Cosa fa

SVOYAGER ID Photo API trasforma un normale ritratto in una foto documentale conforme. ID Photo è un unico prodotto: passaporto, visto, permesso di soggiorno e carta d’identità nazionale sono rappresentati come specifiche del documento, non come prodotti separati. Si carica una foto, si genera un’anteprima con filigrana in base a una specifica, quindi si finalizza per ottenere il risultato senza filigrana.

Anteprima → flusso di lavoro finale

  1. 1Carica una foto. Creare una destinazione di upload e inviare ad essa i byte dell’immagine.
  2. 2Crea una sessione. Generare un'anteprima con filigrana rispetto a una specifica. Esaminare i problemi segnalati.
  3. 3Finalizza. Trasforma la sessione revisionata in un ordine e ricevi il file finale senza filigrana.

Guida rapida

Ogni richiesta viene autenticata con una chiave segreta Bearer. Inizia in modalità di prova:

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 di base e ambienti

Tutti gli endpoint sono accessibili tramite un unico URL di base:

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

Non sono presenti percorsi o parametri di ambiente. Il fatto che una richiesta venga eseguita in ambiente di test o live è determinato interamente dal prefisso della chiave API (svoy_sk_test_… rispetto a svoy_sk_live_…). Le risposte riportano questa informazione come livemode.

Autenticazione

Chiavi API

Autentica ogni richiesta con un'intestazione Authorization contenente la tua chiave segreta. Le chiavi vengono create e sostituite nel Partner Center.

Header
Authorization: Bearer svoy_sk_test_R2p9Kx7YOURKEYHERExxxxxxx

Il prefisso indica l’ambiente: svoy_sk_test_… per l’ambiente di test, svoy_sk_live_… per l’ambiente di produzione. Una chiave di test non può mai operare su dati di produzione (e viceversa); in caso di discrepanza viene restituito il codice di stato 401 wrong_environment.

Ambiti

Le chiavi hanno ambiti espliciti con il principio del privilegio minimo. Una richiesta priva dell’ambito richiesto restituisce il codice di stato 403 insufficient_scope.

AmbitoConcessioni
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.

Proteggere le chiavi

Le chiavi segrete sono destinate esclusivamente alla comunicazione da server a server. Non incorporare mai una chiave segreta nel codice del browser o dell’applicazione mobile, in un repository pubblico o in un bundle lato client. Se una chiave viene esposta, sostituirla immediatamente nel Partner Center.

API di base

Endpoint

I campi obbligatori sono contrassegnati con *. Gli esempi utilizzano credenziali fittizie — mai chiavi reali.

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.

ambito photo.sessions.write
Richiesta
Corpo (application/json)
CampoTipoDescrizione
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.
Esempio di richiesta
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
Risposta · 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"
}
Errori
StatoCodiceQuando
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.

Inoltre, gli errori standard relativi all’autenticazione, alle autorizzazioni e ai limiti di frequenza — vedi Errori e tentativi di ripetizione.

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.

ambito photo.sessions.write Idempotency-Key obbligatorio
Richiesta
Corpo (application/json)
CampoTipoDescrizione
upload_ref*stringThe `upload_ref` from Upload a photo.
spec_id*stringThe `photo_specification` id (`spc_…`) to render against.
Esempio di richiesta
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"}'
Risposta · 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"
}
Errori
StatoCodiceQuando
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.

Inoltre, gli errori standard relativi all’autenticazione, alle autorizzazioni e ai limiti di frequenza — vedi Errori e tentativi di ripetizione.

GET/v1/photo-sessions/{id}

Retrieve a photo session

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

ambito photo.sessions.read
Richiesta
Parametri del percorso
CampoTipoDescrizione
id*stringSession id.
Esempio di richiesta
curl
curl "https://partner.svoyager.com/v1/photo-sessions/3f9c1e77-2b8a-4a1e-9d2c-6b5a4c3d2e10" \
  -H "Authorization: Bearer svoy_sk_test_R2p9Kx7YOURKEYHERExxxxxxx"
Risposta · 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"
}
Errori
StatoCodiceQuando
404session_not_foundNo session matches the id for this account/environment.

Inoltre, gli errori standard relativi all’autenticazione, alle autorizzazioni e ai limiti di frequenza — vedi Errori e tentativi di ripetizione.

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.

ambito photo.sessions.readRestituisce i byte dell’immagine
Richiesta
Parametri del percorso
CampoTipoDescrizione
id*stringSession id.
  • Returns raw `image/*` bytes on success (not JSON).
Esempio di richiesta
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
Risposta · 200

In caso di esito positivo, l’endpoint invia i byte grezzi dell’immagine (non in formato JSON). Salvare il corpo della risposta in un file.

Errori
StatoCodiceQuando
404preview_not_foundThe session or its preview does not exist.

Inoltre, gli errori standard relativi all’autenticazione, alle autorizzazioni e ai limiti di frequenza — vedi Errori e tentativi di ripetizione.

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.

ambito photo.finalize.write Idempotency-Key obbligatorio
Richiesta
Parametri del percorso
CampoTipoDescrizione
id*stringSession id to finalize.
Esempio di richiesta
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"
Risposta · 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"
}
Errori
StatoCodiceQuando
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.

Inoltre, gli errori standard relativi all’autenticazione, alle autorizzazioni e ai limiti di frequenza — vedi Errori e tentativi di ripetizione.

GET/v1/orders/{id}

Retrieve an order

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

ambito photo.orders.read
Richiesta
Parametri del percorso
CampoTipoDescrizione
id*stringOrder id.
Esempio di richiesta
curl
curl "https://partner.svoyager.com/v1/orders/8a2d5b40-71c6-4f0e-b3a9-1e7c9d05f284" \
  -H "Authorization: Bearer svoy_sk_live_A8m4Qz1YOURKEYHERExxxxxxx"
Risposta · 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"
}
Errori
StatoCodiceQuando
404order_not_foundNo order matches the id for this account/environment.

Inoltre, gli errori standard relativi all’autenticazione, alle autorizzazioni e ai limiti di frequenza — vedi Errori e tentativi di ripetizione.

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.

ambito photo.orders.readRestituisce i byte dell’immagine
Richiesta
Parametri del percorso
CampoTipoDescrizione
id*stringOrder id.
  • Returns raw `image/*` bytes on success (not JSON).
Esempio di richiesta
curl
curl "https://partner.svoyager.com/v1/orders/8a2d5b40-71c6-4f0e-b3a9-1e7c9d05f284/final" \
  -H "Authorization: Bearer svoy_sk_live_A8m4Qz1YOURKEYHERExxxxxxx" \
  --output final.jpg
Risposta · 200

In caso di esito positivo, l’endpoint invia i byte grezzi dell’immagine (non in formato JSON). Salvare il corpo della risposta in un file.

Errori
StatoCodiceQuando
404final_not_foundThe order or its final does not exist.

Inoltre, gli errori standard relativi all’autenticazione, alle autorizzazioni e ai limiti di frequenza — vedi Errori e tentativi di ripetizione.

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.

ambito photo.specs.read
Richiesta
Parametri di query
CampoTipoDescrizione
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`.
Esempio di richiesta
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"
Risposta · 200
200 · application/json
{
  "object": "list",
  "data": [
    {
      "object": "photo_specification",
      "id": "spc_9wTv2c1Kd8Qe",
      "name": "United States Passport"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
Errori

Questo endpoint restituisce solo gli errori standard indicati di seguito.

Inoltre, gli errori standard relativi all’autenticazione, alle autorizzazioni e ai limiti di frequenza — vedi Errori e tentativi di ripetizione.

GET/v1/photo-specifications/{id}

Retrieve a photo specification

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

ambito photo.specs.read
Richiesta
Parametri del percorso
CampoTipoDescrizione
id*stringSpecification id (`spc_…`).
Esempio di richiesta
curl
curl "https://partner.svoyager.com/v1/photo-specifications/spc_9wTv2c1Kd8Qe" \
  -H "Authorization: Bearer svoy_sk_test_R2p9Kx7YOURKEYHERExxxxxxx"
Risposta · 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"
}
Errori
StatoCodiceQuando
404spec_not_foundNo active specification matches the id.

Inoltre, gli errori standard relativi all’autenticazione, alle autorizzazioni e ai limiti di frequenza — vedi Errori e tentativi di ripetizione.

Inviare un'intestazione Idempotency-Key (un valore univoco, ad esempio un UUID) in modo che una richiesta ripetuta non venga mai addebitata o elaborata due volte. È richiesta nei seguenti casi:

  • POST /v1/photo-sessions
  • POST /v1/photo-sessions/{id}/finalize
  • Stessa chiave + stesso corpo → viene riprodotto il risultato originale (nessun secondo addebito, nessun secondo rendering).
  • Stessa chiave + corpo diverso → 409 idempotency_key_reuse.
  • Un errore che consente il riprovare permette di riprovare con la stessa chiave, lo stesso corpo e lo stesso upload_ref.
  • Le richieste di finalizzazione simultanee per una singola sessione non possono mai creare o addebitare due ordini.

Una sessione passa attraverso gli stati di anteprima; un ordine attraverso gli stati di finalizzazione.

Stato della sessione
  • preview_readyAnteprima generata, nessun problema.
  • preview_has_issuesanteprima generata con problemi.
  • preview_failedNon è stato possibile generare l’anteprima.
  • finalizedla sessione è stata conclusa.
Stato dell’ordine
  • final_readyLa versione finale è disponibile.
  • processingLa versione finale è in fase di preparazione.
  • failedFinalizzazione non riuscita.

L’ambiente è determinato dal prefisso della chiave — i client non possono mai modificarlo. La modalità di test esegue l’anteprima reale con filigrana, consentendo di simulare il flusso effettivo, ma emula l’ambiente finale, quindi non vengono utilizzate quote live né rendering di produzione.

AspectTestLive
livemodefalsetrue
AnteprimaReale, con filigranaReale, con filigrana
FinaleSandbox emulata dall’anteprimaAutentico, senza filigrana
sandbox_emulatedtruefalse
watermarkedtruefalse
Quota consumataSolo quota di provaSolo quota live

Il tuo piano include un numero di anteprime e versioni definitive per periodo, conteggiate separatamente. La creazione di una sessione consuma un'anteprima; la finalizzazione consuma una versione definitiva. La quota viene riservata in modo atomico prima dell'elaborazione.

  • Quando l’anteprima inclusa o la quota finale è esaurita, la richiesta restituisce il codice di stato 402 quota_exceeded.
  • Il codice 402 rappresenta un blocco definitivo: i tentativi successivi non andranno a buon fine fino al periodo successivo o a un cambio di piano.
  • Le quote di test e quelle di produzione sono completamente indipendenti.

Ogni errore utilizza un unico involucro. L’ID della richiesta (request_id) compare anche nell’intestazione di risposta X-Request-Id: includerlo nelle richieste di assistenza.

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

Errori standard (tutti gli endpoint)

StatoCodiceQuando
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`.

Il codice 422 viene restituito solo in caso di un problema confermato relativo all’immagine. Il codice 402 indica che la quota è esaurita. Il codice 409 indica un conflitto di idempotenza o di risorse.

Il codice 429 indica che è stato raggiunto il limite di frequenza per chiave: rispettare l’intestazione Retry-After. Per i codici 502/503 e altri 5xx, riprovare con un backoff e la stessa Idempotency-Key.

Un'anteprima può restituire zero o più problemi, ciascuno costituito da un codice stabile + un messaggio. Mostrali all'utente finale in modo che possa scattare nuovamente la foto. Un segnale a monte non riconosciuto viene declassato a "altro".

CodiceMessaggio
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.
  • Le anteprime e le versioni definitive vengono fornite esclusivamente da URL autenticati ospitati da SVOYAGER. L’accesso richiede la tua chiave API e l’ambito corretto: l’archivio sottostante non viene mai reso pubblico.
  • Le immagini caricate sono private e limitate al proprio account e al proprio ambiente; le destinazioni di caricamento hanno una durata limitata e sono monouso.
  • Le foto dei documenti vengono elaborate per ottenere il risultato e non vengono condivise tra account diversi.

Consultare i termini di SVOYAGER relativi al trattamento, alla conservazione e alla cancellazione dei dati:Informativa sulla privacy ·Accordo di partnership e termini