# Adding selfie checks Learn how to add face similarity checks to prevent fraudsters from using stolen documents. While [document checks](https://docs.stripe.com/identity/verification-checks.md?type=document) provide a defense against the use of fraudulent identity documents, it’s possible for fraudsters to get access to legitimate stolen documents. To prevent this, Stripe Identity can perform selfie checks on your users. Selfie checks look for distinguishing biological traits, such as face geometry, from a photo ID and a picture of your user’s face. Stripe then uses advanced machine learning algorithms to ensure the face pictures belong to the same person. To add selfie checks to your application, first follow the guide to [collect and verify identity documents](https://docs.stripe.com/identity/verify-identity-documents.md). ## Adding selfie checks to VerificationSessions When [creating a VerificationSession](https://docs.stripe.com/api/identity/verification_sessions/create.md), use the [options.document.require_matching_selfie](https://docs.stripe.com/api/identity/verification_sessions/create.md#create_identity_verification_session-options-document-require_matching_selfie) parameter to enable selfie checks. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Identity.VerificationSessionCreateOptions { Type = "document", Options = new Stripe.Identity.VerificationSessionOptionsOptions { Document = new Stripe.Identity.VerificationSessionOptionsDocumentOptions { RequireMatchingSelfie = true, }, }, }; var service = new Stripe.Identity.VerificationSessionService(); Stripe.Identity.VerificationSession verificationSession = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.IdentityVerificationSessionParams{ Type: stripe.String(string(stripe.IdentityVerificationSessionTypeDocument)), Options: &stripe.IdentityVerificationSessionOptionsParams{ Document: &stripe.IdentityVerificationSessionOptionsDocumentParams{ RequireMatchingSelfie: stripe.Bool(true), }, }, }; result, err := verificationsession.New(params); ``` ```java Stripe.apiKey = "<>"; VerificationSessionCreateParams params = VerificationSessionCreateParams.builder() .setType(VerificationSessionCreateParams.Type.DOCUMENT) .setOptions( VerificationSessionCreateParams.Options.builder() .setDocument( VerificationSessionCreateParams.Options.Document.builder() .setRequireMatchingSelfie(true) .build() ) .build() ) .build(); VerificationSession verificationSession = VerificationSession.create(params); ``` ```node const stripe = require('stripe')('<>'); const verificationSession = await stripe.identity.verificationSessions.create({ type: 'document', options: { document: { require_matching_selfie: true, }, }, }); ``` ```python import stripe stripe.api_key = "<>" verification_session = stripe.identity.VerificationSession.create( type="document", options={"document": {"require_matching_selfie": True}}, ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $verificationSession = $stripe->identity->verificationSessions->create([ 'type' => 'document', 'options' => ['document' => ['require_matching_selfie' => true]], ]); ``` ```ruby Stripe.api_key = '<>' verification_session = Stripe::Identity::VerificationSession.create({ type: 'document', options: {document: {require_matching_selfie: true}}, }) ``` This configures the verification flow to require a photo ID and a face picture from your user. ## Accessing selfie check results After it’s submitted and processed, the VerificationSession [status](https://docs.stripe.com/identity/how-sessions-work.md) changes depending on the result of the checks: - `verified` — Both the document and selfie checks were successful. The session [verified_outputs](https://docs.stripe.com/api/identity/verification_sessions/object.md#identity_verification_session_object-verified_outputs) contains extracted information from the document. - `requires_input` — At least one of the document or the selfie checks failed. To access the captured selfie and document images, you’ll need to retrieve the associated [VerificationReport](https://docs.stripe.com/api/identity/verification_reports.md), you can do this by [expanding](https://docs.stripe.com/api/expanding_objects.md) the [last_verification_report](https://docs.stripe.com/api/identity/verification_sessions/object.md#identity_verification_session_object-last_verification_report) field in the session: ```javascript <> const verificationSession = await stripe.identity.verificationSessions.retrieve( '{{SESSION_ID}}', { expand: ['last_verification_report'], } ); const verificationReport = verificationSession.last_verification_report; ``` ```ruby <> verification_session = Stripe::Identity::VerificationSession.retrieve({ id: '{{SESSION_ID}}', expand: ['last_verification_report'], }) verification_report = verification_session.last_verification_report ``` ```python <> verification_session = stripe.identity.VerificationSession.retrieve( '{{SESSION_ID}}', expand=['last_verification_report'], ) verification_report = verification_session.last_verification_report ``` ```php // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys $stripe = new \Stripe\StripeClient(<>); $verification_session = $stripe->identity->verificationSessions->retrieve( '{{SESSION_ID}}', [ 'expand' => ['last_verification_report'], ] ); $verification_report = $verification_session->last_verification_report; ``` ```java <> VerificationSessionRetrieveParams params = VerificationSessionRetrieveParams.builder() .addExpand("last_verification_report") .build(); VerificationSession verificationSession = VerificationSession.retrieve("{{SESSION_ID}}", params, null); VerificationReport verificationReport = verificationSession.getLastVerificationReportObject(); ``` ```go <> params := &stripe.IdentityVerificationSessionParams{} params.AddExpand("last_verification_report") vs, _ := verificationsession.Get("{{SESSION_ID}}", params) verification_report := vs.LastVerificationReport ``` ```dotnet <> var options = new VerificationSessionGetOptions(); options.AddExpand("last_verification_report"); var service = new VerificationSessionService(); var verificationSession = service.Get("{{SESSION_ID}}", options); var verificationReport = verificationSession.LastVerificationReport; ``` The VerificationReport has [document](https://docs.stripe.com/api/identity/verification_reports/object.md#identity_verification_report_object-document) and [selfie](https://docs.stripe.com/api/identity/verification_reports/object.md#identity_verification_report_object-selfie) fields holding the results of the document and selfie checks. Here’s an example VerificationReport with successful document and selfie checks: ```json { "id": "vr_", "object": "identity.verification_report", "type": "document", "verification_session": "vs_", "created": 1611776872, "livemode": true, "options": { "document": { "require_matching_selfie": true } }, "document": { "status": "verified", "error": null, "first_name": "Jenny", "last_name": "Rosen", "address": { "line1": "1234 Main St.", "city": "San Francisco", "state": "CA", "postal_code": "94111", "country": "US" }, "document_type": "id_card", "expiration_date": { "day": 17, "month": 7, "year": 2024 }, "files": ["file_", "file_"], "issued_date": { "day": 4, "month": 27, "year": 2021 }, "issuing_country": "US" }, "selfie": { "status": "verified", "error": null, "document": "file_", "selfie": "file_", } } ``` To access the collected document and face images, see [Accessing verification results](https://docs.stripe.com/identity/access-verification-results.md). ## Understanding selfie check failures The [document](https://docs.stripe.com/api/identity/verification_reports/object.md#identity_verification_report_object-document) and [selfie](https://docs.stripe.com/api/identity/verification_reports/object.md#identity_verification_report_object-selfie) VerificationReport fields contain the collected data as well as a `status` and `error` fields to help you understand whether the check is successful or not. The `status` field tells you whether each check is successful or not. The possible values are: - `verified` - The verification check is successful and the collected data is verified. - `unverified` - The verification check failed. You can check the `error` hash for more information. When the verification check fails, the `error` field contains `code` and `reason` values to explain the verification failure. The `error.code` field can be used to programmatically handle verification failures. The `reason` field contains a descriptive message explaining the failure reason and can be shown to your user. ### Document check failures Failure details are available in the report [document.error](https://docs.stripe.com/api/identity/verification_reports/object.md#identity_verification_report_object-document-error) field. | Error code | Description | | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `document_expired` | The provided identity document has expired. | | `document_unverified_other` | Stripe couldn’t verify the provided identity document. [See list of supported document types](https://docs.stripe.com/identity/verification-checks.md?type=document). | | `document_type_not_supported` | The provided identity document isn’t one of the session’s [allowed document types](https://docs.stripe.com/api/identity/verification_sessions/create.md#create_identity_verification_session-options-document-allow_document_types). | ### Selfie check failures Failure details are available in the report [selfie.error](https://docs.stripe.com/api/identity/verification_reports/object.md#identity_verification_report_object-selfie-error) field. | Error code | Description | | ------------------------------- | ------------------------------------------------------------------- | | `selfie_document_missing_photo` | The provided identity document did not contain a picture of a face. | | `selfie_face_mismatch` | The captured face image did not match with the document’s face. | | `selfie_unverified_other` | Stripe couldn’t verify the provided selfie. | | `selfie_manipulated` | The captured face image was manipulated. | ## See Also * [Verify your users’ identity documents](https://docs.stripe.com/identity/verify-identity-documents.md) * [The Verification Sessions API](https://docs.stripe.com/identity/verification-sessions.md#create)