diff --git a/CHANGELOG.md b/CHANGELOG.md
index 11b60e4..3f2f22e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,21 @@ All notable changes to the Smile Identity API specifications will be documented
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
## [Unreleased]
+## [v3.639.0] - 2026-06-05
+
+### Changed
+- Updated `v3-biometric-authentication-entry`
+- Updated `v3-biometric-enrollment-entry`
+- Updated `v3-biometric-kyc-entry`
+- Updated `v3-document-verification-entry`
+- Updated `v3-enhanced-document-verification-entry`
+- Updated `v3-enhanced-kyc-entry`
+- Updated `v3-report-user-fraud`
+- Updated `v3-smart-selfie-compare-entry`
+
+### Removed
+- `v3-block-user`
+
## [v3.619.0] - 2026-05-29
### Changed
diff --git a/README.md b/README.md
index 8498967..685b691 100644
--- a/README.md
+++ b/README.md
@@ -10,11 +10,11 @@ OpenAPI 3.0 specifications for the Smile Identity v3 API.
| [Biometric Authentication](specs/v3/v3-biometric-authentication-entry.yaml) | `POST /v3/authentication` | Submit biometric authentication |
| [Biometric Enrollment](specs/v3/v3-biometric-enrollment-entry.yaml) | `POST /v3/registration` | Submit biometric enrollment |
| [Biometric KYC](specs/v3/v3-biometric-kyc-entry.yaml) | `POST /v3/biometric_kyc` | Submit Biometric KYC verification |
-| [Block User](specs/v3/v3-block-user.yaml) | `POST /v3/users/{user_id}` | Block or unblock an enrolled user |
| [Document Verification](specs/v3/v3-document-verification-entry.yaml) | `POST /v3/document-verification` | Submit Document Verification |
| [Enhanced Document Verification](specs/v3/v3-enhanced-document-verification-entry.yaml) | `POST /v3/enhanced-document-verification` | Submit Enhanced Document Verification |
| [Enhanced KYC](specs/v3/v3-enhanced-kyc-entry.yaml) | `POST /v3/enhanced_kyc` | Submit Enhanced KYC verification |
| [Replay Callback](specs/v3/v3-replay-callback.yaml) | `POST /v3/replay/{job_id}` | Replay a callback for a completed verification |
+| [Report User Fraud](specs/v3/v3-report-user-fraud.yaml) | `POST /v3/users/{user_id}/report_fraud` | Flag or clear fraud status for a user |
| [Services](specs/v3/v3-services.yaml) | `GET /v3/services/bank_codes` | List bank codes |
| [Services](specs/v3/v3-services.yaml) | `GET /v3/services/id_status` | Get ID type availability status |
| [Services](specs/v3/v3-services.yaml) | `GET /v3/services/supported_documents` | List supported documents for verification |
diff --git a/docs/index.html b/docs/index.html
index 677cc2a..30d7b6b 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -198,11 +198,11 @@
APIs
{ file: "v3-biometric-authentication-entry", label: "Biometric Authentication" },
{ file: "v3-biometric-enrollment-entry", label: "Biometric Enrollment" },
{ file: "v3-biometric-kyc-entry", label: "Biometric KYC" },
- { file: "v3-block-user", label: "Block User" },
{ file: "v3-document-verification-entry", label: "Document Verification" },
{ file: "v3-enhanced-document-verification-entry", label: "Enhanced Document Verification" },
{ file: "v3-enhanced-kyc-entry", label: "Enhanced KYC" },
{ file: "v3-replay-callback", label: "Replay Callback" },
+ { file: "v3-report-user-fraud", label: "Report User Fraud" },
{ file: "v3-services", label: "Services" },
{ file: "v3-smart-selfie-compare-entry", label: "Smart Selfie Compare" },
{ file: "v3-token", label: "Token" },
diff --git a/specs/v3/v3-biometric-authentication-entry.yaml b/specs/v3/v3-biometric-authentication-entry.yaml
index 46ef80d..0ef895a 100644
--- a/specs/v3/v3-biometric-authentication-entry.yaml
+++ b/specs/v3/v3-biometric-authentication-entry.yaml
@@ -99,6 +99,11 @@ paths:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples:
+ missingCallbackUrl:
+ summary: Missing callback_url and no default set
+ value:
+ status: Bad Request
+ message: A valid callback_url is required in the request or a default callback URL must be configured in the portal.
missingUserId:
summary: Missing user_id
value:
diff --git a/specs/v3/v3-biometric-enrollment-entry.yaml b/specs/v3/v3-biometric-enrollment-entry.yaml
index 7798f16..cdfee54 100644
--- a/specs/v3/v3-biometric-enrollment-entry.yaml
+++ b/specs/v3/v3-biometric-enrollment-entry.yaml
@@ -111,6 +111,11 @@ paths:
value:
status: Bad Request
message: liveness_images must contain at least 6 images.
+ missingCallbackUrl:
+ summary: Missing callback_url and no default set
+ value:
+ status: Bad Request
+ message: A valid callback_url is required in the request or a default callback URL must be configured in the portal.
missingContact:
summary: Missing email and phone
value:
diff --git a/specs/v3/v3-biometric-kyc-entry.yaml b/specs/v3/v3-biometric-kyc-entry.yaml
index 4fa4ecc..fc2ca0e 100644
--- a/specs/v3/v3-biometric-kyc-entry.yaml
+++ b/specs/v3/v3-biometric-kyc-entry.yaml
@@ -120,6 +120,11 @@ paths:
value:
status: Bad Request
message: liveness_images must contain at least 6 images.
+ missingCallbackUrl:
+ summary: Missing callback_url and no default set
+ value:
+ status: Bad Request
+ message: A valid callback_url is required in the request or a default callback URL must be configured in the portal.
missingCountry:
summary: Missing required field
value:
diff --git a/specs/v3/v3-block-user.yaml b/specs/v3/v3-block-user.yaml
deleted file mode 100644
index 69c90c0..0000000
--- a/specs/v3/v3-block-user.yaml
+++ /dev/null
@@ -1,261 +0,0 @@
-openapi: 3.0.3
-info:
- title: V3 Block User API
- version: 1.0.0
- description: |
- Block or unblock an enrolled user. Updates the user's fraud status,
- active/deleted/allow_new_enroll state, and optionally marks associated verifications as
- confirmed fraud.
-
- The `user_id` is specified in the URL path. The partner is identified from the
- JWT token provided via the `SmileID-Token` header (obtained from
- `POST /v3/token`).
-
- **Authentication**: Only JWT token auth is supported. Signature-based auth
- (`smileid-request-signature` / `smileid-timestamp`) is not accepted.
-
-servers:
- - url: https://api.smileidentity.com
- description: Production
- - url: https://testapi.smileidentity.com
- description: Sandbox
- - url: https://devapi.smileidentity.com
- description: Development
-
-components:
- securitySchemes:
- SmileIDToken:
- type: apiKey
- in: header
- name: SmileID-Token
- description: JWT token obtained from `POST /v3/token`.
-
- schemas:
- BlockUserRequest:
- type: object
- description: |
- At least one of `is_fraudulent`, `active`, `allow_new_enroll`, or `deleted`
- must be provided. Additional properties are not allowed.
- properties:
- is_fraudulent:
- type: boolean
- description: |
- Set to `true` to mark the user as fraudulent (block), or `false` to
- remove the fraud flag (unblock).
- example: true
- update_jobs:
- type: boolean
- description: |
- When `true` **and** `is_fraudulent` is also provided, updates the
- confirmed-fraud status on all verifications associated with this user. If
- unblocking (`is_fraudulent: false`), also re-allows any previously-blocked
- biometric matches linked to those verifications.
- example: true
- active:
- type: boolean
- description: |
- Set to `true` to mark the enrollee as active, or `false` to mark
- inactive. Internally stored as `inactive = !active`.
- example: true
- allow_new_enroll:
- type: boolean
- description: |
- Set to `true` to allow the user to re-enroll, or `false` to prevent
- re-enrollment.
- example: true
- deleted:
- type: boolean
- description: Soft-delete (`true`) or restore (`false`) the enrollee record.
- example: false
- additionalProperties: false
-
- BlockUserSuccessResponse:
- type: object
- required:
- - message
- - status
- properties:
- message:
- type: string
- description: Human-readable result message.
- example: Enrollee user updated
- status:
- type: string
- description: Operation status.
- example: OK
-
- ErrorResponse:
- type: object
- required:
- - message
- - status
- properties:
- message:
- type: string
- description: Human-readable error message.
- example: Enrollee not found
- status:
- type: string
- description: HTTP status text.
- example: Not Found
-
-security:
- - SmileIDToken: []
-
-paths:
- /v3/users/{user_id}:
- post:
- operationId: blockUser
- summary: Block or unblock an enrolled user
- description: |
- Updates an enrolled user's fraud status and/or enrollee state fields.
- The partner is identified from the JWT token; `user_id` is taken from the
- URL path.
-
- **Blocking a user** (`is_fraudulent: true`):
- - Creates a new fraud record for the enrollee.
- - Optionally (`update_jobs: true`) creates confirmed-fraud entries for all
- associated verifications.
-
- **Unblocking a user** (`is_fraudulent: false`):
- - Creates a new fraud record clearing the fraud flag.
- - Optionally (`update_jobs: true`) soft-deletes confirmed-fraud entries and
- re-allows previously-blocked biometric matches for associated verifications.
-
- **Updating enrollee state** (`active`, `allow_new_enroll`, `deleted`):
- - Updates the corresponding fields on the enrollee record.
- - Only fields present in the request body are modified; omitted fields are
- left unchanged.
-
- A single indexing message is emitted after all database updates to ensure
- the search index reflects the final state.
- security:
- - SmileIDToken: []
- parameters:
- - name: user_id
- in: path
- required: true
- description: |
- The partner-scoped user identifier of the enrolled user to update.
- This is the `user_id` value originally provided during enrollment.
- schema:
- type: string
- example: user-123
- requestBody:
- required: true
- description: |
- At least one actionable field (`is_fraudulent`, `active`,
- `allow_new_enroll`, or `deleted`) must be provided. `update_jobs` alone
- is not sufficient.
- content:
- multipart/form-data:
- schema:
- $ref: '#/components/schemas/BlockUserRequest'
- examples:
- block:
- summary: Block a user and update verifications
- value:
- is_fraudulent: true
- update_jobs: true
- unblock:
- summary: Unblock a user and restore verifications
- value:
- is_fraudulent: false
- update_jobs: true
- updateState:
- summary: Update enrollee state only
- value:
- active: true
- allow_new_enroll: true
- deleted: false
- fullUpdate:
- summary: Block user and update all fields
- value:
- active: false
- allow_new_enroll: false
- deleted: false
- is_fraudulent: true
- update_jobs: true
- responses:
- '200':
- description: Enrollee updated successfully.
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/BlockUserSuccessResponse'
- example:
- message: Enrollee user updated
- status: OK
- '400':
- description: |
- Validation error. Possible causes:
- - `user_id` path parameter is missing.
- - Request body is empty or missing all actionable fields.
- - Unknown fields in request body.
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorResponse'
- example:
- message: '"value" must contain at least one of [active, allow_new_enroll, deleted, is_fraudulent]'
- status: Bad Request
- '401':
- description: Authentication failed (invalid or missing token).
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorResponse'
- example:
- message: Invalid token
- status: Unauthorized
- '402':
- description: Insufficient wallet balance.
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorResponse'
- example:
- message: You are out of credits. Add funds to your wallet to run more verifications.
- status: Payment Required
- '403':
- description: |
- Access denied. Possible causes:
- - Production mode not enabled for partner.
- - IP address is blocked.
- - IP not in partner's allowlist.
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorResponse'
- example:
- message: You are not authorized to do that.
- status: Forbidden
- '404':
- description: No enrollee found for the given `user_id` and partner.
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorResponse'
- example:
- message: Enrollee not found
- status: Not Found
- '415':
- description: |
- Wrong or missing `Content-Type` header. The request body must be sent
- as `multipart/form-data`.
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorResponse'
- example:
- message: Unsupported Media Type. Required Content-Type is multipart/form-data
- status: Unsupported Media Type
- '500':
- description: Unexpected server error.
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorResponse'
- example:
- message: System Error
- status: Internal Server Error
diff --git a/specs/v3/v3-document-verification-entry.yaml b/specs/v3/v3-document-verification-entry.yaml
index b35aae2..cc7bf34 100644
--- a/specs/v3/v3-document-verification-entry.yaml
+++ b/specs/v3/v3-document-verification-entry.yaml
@@ -130,6 +130,11 @@ paths:
value:
status: Bad Request
message: liveness_images must contain at least 6 images.
+ missingCallbackUrl:
+ summary: Missing callback_url and no default set
+ value:
+ status: Bad Request
+ message: A valid callback_url is required in the request or a default callback URL must be configured in the portal.
missingCountry:
summary: Missing required field
value:
diff --git a/specs/v3/v3-enhanced-document-verification-entry.yaml b/specs/v3/v3-enhanced-document-verification-entry.yaml
index f7031e8..cecfecf 100644
--- a/specs/v3/v3-enhanced-document-verification-entry.yaml
+++ b/specs/v3/v3-enhanced-document-verification-entry.yaml
@@ -135,6 +135,11 @@ paths:
value:
status: Bad Request
message: liveness_images must contain at least 6 images.
+ missingCallbackUrl:
+ summary: Missing callback_url and no default set
+ value:
+ status: Bad Request
+ message: A valid callback_url is required in the request or a default callback URL must be configured in the portal.
missingCountry:
summary: Missing required field
value:
diff --git a/specs/v3/v3-enhanced-kyc-entry.yaml b/specs/v3/v3-enhanced-kyc-entry.yaml
index e3e4c1d..94648b2 100644
--- a/specs/v3/v3-enhanced-kyc-entry.yaml
+++ b/specs/v3/v3-enhanced-kyc-entry.yaml
@@ -97,6 +97,11 @@ paths:
value:
status: Bad Request
message: "Required field 'country' is missing or invalid."
+ missingCallbackUrl:
+ summary: Missing callback_url and no default set
+ value:
+ status: Bad Request
+ message: A valid callback_url is required in the request or a default callback URL must be configured in the portal.
missingContact:
summary: Missing email and phone
value:
diff --git a/specs/v3/v3-report-user-fraud.yaml b/specs/v3/v3-report-user-fraud.yaml
new file mode 100644
index 0000000..c95b45c
--- /dev/null
+++ b/specs/v3/v3-report-user-fraud.yaml
@@ -0,0 +1,287 @@
+openapi: 3.0.3
+info:
+ title: V3 Report User Fraud API
+ version: 1.0.0
+ description: |
+ Allows a partner to flag (or clear the flag for) a verified user as
+ fraudulent. Flagging a user prevents subsequent verifications that match
+ the same face, device, or biometric cluster. Clearing the flag reverses
+ those effects.
+
+ The `user_id` is specified in the URL path. The partner is identified from
+ the JWT token provided via the `SmileID-Token` header (obtained from
+ `POST /v3/token`).
+
+ **Authentication**: JWT token auth. The request IP must also pass the
+ partner's IP allowlist (when configured) and must not appear on the IP
+ blocklist.
+
+servers:
+ - url: https://api.smileidentity.com
+ description: Production
+ - url: https://testapi.smileidentity.com
+ description: Sandbox
+ - url: https://devapi.smileidentity.com
+ description: Development
+
+components:
+ securitySchemes:
+ SmileIDToken:
+ type: apiKey
+ in: header
+ name: SmileID-Token
+ description: JWT token obtained from `POST /v3/token`.
+
+ schemas:
+ ReportUserFraudRequest:
+ type: object
+ required:
+ - is_fraud
+ - reported_by
+ properties:
+ is_fraud:
+ type: boolean
+ description: |
+ `true` to flag the user as fraudulent, `false` to clear a previous
+ fraud flag.
+ example: true
+ reason:
+ type: string
+ description: |
+ Reason for the fraud report. **Required when `is_fraud` is `true`**;
+ ignored when `is_fraud` is `false`. If `OTHER` is selected, `notes`
+ becomes required.
+ enum:
+ - FIRST_PARTY_FRAUD
+ - SECOND_PARTY_FRAUD
+ - THIRD_PARTY_FRAUD
+ - SYNTHETIC_IDENTITY
+ - ACCOUNT_TAKEOVER
+ - DOCUMENT_FORGERY
+ - IDENTITY_FARMING
+ - MULE_ACCOUNT
+ - OTHER
+ example: FIRST_PARTY_FRAUD
+ notes:
+ type: string
+ maxLength: 500
+ description: |
+ Free-form notes describing the fraud report. **Required when**
+ either `is_fraud` is `false` or `reason` is `OTHER`. Optional in
+ all other cases. Capped at 500 characters.
+ example: Account takeover confirmed via partner internal review.
+ reported_by:
+ type: string
+ format: email
+ description: Email address of the person submitting the report.
+ example: risk@partner.example
+ additionalProperties: true
+
+ ReportUserFraudAcceptedResponse:
+ type: object
+ required:
+ - status
+ - user_id
+ properties:
+ status:
+ type: string
+ enum: [accepted]
+ description: Always `accepted` when the request was queued for processing.
+ example: accepted
+ message:
+ type: string
+ description: Human-readable result message.
+ example: Fraud report accepted
+ user_id:
+ type: string
+ description: The `user_id` that was reported.
+ example: user-123
+
+ ErrorResponse:
+ type: object
+ required:
+ - message
+ - status
+ properties:
+ message:
+ type: string
+ description: Human-readable error message.
+ example: "Required field 'reason' is missing or invalid."
+ status:
+ type: string
+ description: HTTP status text.
+ example: Bad Request
+
+security:
+ - SmileIDToken: []
+
+paths:
+ /v3/users/{user_id}/report_fraud:
+ post:
+ operationId: reportUserFraud
+ summary: Flag or clear fraud status for a user
+ description: |
+ Records a fraud report (or fraud-clearance) for a previously enrolled
+ user.
+
+ Use `is_fraud: true` to flag a user as fraudulent, or `is_fraud: false`
+ to clear a previous flag. Flagging propagates the user's face, device,
+ and biometric clusters to the relevant block lists so that subsequent
+ verifications matching them are rejected. Clearing the flag reverses
+ these effects.
+
+ The response is `202 Accepted` once the request has been validated
+ and handled.
+ security:
+ - SmileIDToken: []
+ parameters:
+ - name: user_id
+ in: path
+ required: true
+ description: |
+ The partner-scoped user identifier of the enrolled user being
+ reported. This is the `user_id` value originally provided during
+ enrollment.
+ schema:
+ type: string
+ example: user-123
+ requestBody:
+ required: true
+ content:
+ multipart/form-data:
+ schema:
+ $ref: '#/components/schemas/ReportUserFraudRequest'
+ examples:
+ flagFirstParty:
+ summary: Flag a user (reason only)
+ value:
+ is_fraud: true
+ reason: FIRST_PARTY_FRAUD
+ reported_by: risk@partner.example
+ flagWithNotes:
+ summary: Flag a user with optional notes
+ value:
+ is_fraud: true
+ reason: ACCOUNT_TAKEOVER
+ notes: Confirmed via partner internal review
+ reported_by: risk@partner.example
+ flagOther:
+ summary: Flag a user with reason=OTHER (notes required)
+ value:
+ is_fraud: true
+ reason: OTHER
+ notes: Bespoke fraud pattern observed by internal review
+ reported_by: risk@partner.example
+ clearFlag:
+ summary: Clear a previous fraud flag (notes required)
+ value:
+ is_fraud: false
+ notes: Cleared by appeals review
+ reported_by: risk@partner.example
+ responses:
+ '202':
+ description: Fraud report accepted and queued for processing.
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ReportUserFraudAcceptedResponse'
+ example:
+ status: accepted
+ message: Fraud report accepted
+ user_id: user-123
+ '400':
+ description: |
+ Validation error. Possible causes:
+ - `user_id` path parameter is missing.
+ - `is_fraud` is missing or not a boolean.
+ - `reason` is missing when `is_fraud` is `true`, or is not one of
+ the allowed values.
+ - `notes` is missing when `is_fraud` is `false` or `reason` is
+ `OTHER`.
+ - `notes` exceeds 500 characters.
+ - `reported_by` is missing or is not a valid email address.
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ examples:
+ missingReason:
+ summary: Missing reason when flagging
+ value:
+ message: "Required field 'reason' is missing or invalid."
+ status: Bad Request
+ invalidReason:
+ summary: Unrecognised reason value
+ value:
+ message: "Field 'reason' must be one of: FIRST_PARTY_FRAUD, SECOND_PARTY_FRAUD, THIRD_PARTY_FRAUD, SYNTHETIC_IDENTITY, ACCOUNT_TAKEOVER, DOCUMENT_FORGERY, IDENTITY_FARMING, MULE_ACCOUNT, OTHER."
+ status: Bad Request
+ missingNotesOnUnblock:
+ summary: Missing notes when clearing
+ value:
+ message: "Required field 'notes' is missing or invalid when is_fraud is false."
+ status: Bad Request
+ missingNotesOnOther:
+ summary: Missing notes when reason=OTHER
+ value:
+ message: "Required field 'notes' is missing or invalid when reason is 'OTHER'."
+ status: Bad Request
+ notesTooLong:
+ summary: Notes exceed maximum length
+ value:
+ message: "Field 'notes' must be at most 500 characters."
+ status: Bad Request
+ invalidEmail:
+ summary: Invalid reporter email
+ value:
+ message: "Field 'reported_by' must be a valid email address."
+ status: Bad Request
+ '401':
+ description: Authentication failed (invalid or missing token).
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ message: Invalid token
+ status: Unauthorized
+ '403':
+ description: |
+ Access denied. Possible causes:
+ - IP address is on the blocklist.
+ - IP not in partner's allowlist.
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ message: You are not authorized to do that.
+ status: Forbidden
+ '404':
+ description: No enrollee found for the given `user_id` and partner.
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ message: User not found
+ status: Not Found
+ '415':
+ description: |
+ Wrong or missing `Content-Type` header. The request body must be
+ sent as `multipart/form-data`.
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ message: Unsupported Media Type. Required Content-Type is multipart/form-data
+ status: Unsupported Media Type
+ '500':
+ description: Unexpected server error.
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ message: System Error
+ status: Internal Server Error
diff --git a/specs/v3/v3-smart-selfie-compare-entry.yaml b/specs/v3/v3-smart-selfie-compare-entry.yaml
index b66e1b1..edef7f2 100644
--- a/specs/v3/v3-smart-selfie-compare-entry.yaml
+++ b/specs/v3/v3-smart-selfie-compare-entry.yaml
@@ -99,6 +99,11 @@ paths:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples:
+ missingCallbackUrl:
+ summary: Missing callback_url and no default set
+ value:
+ status: Bad Request
+ message: A valid callback_url is required in the request or a default callback URL must be configured in the portal.
missingSelfie:
summary: Missing selfie image
value: