Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

## [v3.821.0] - 2026-08-12

### Changed
- Updated `openapi`
- 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-token`


## [v3.818.0] - 2026-08-10

### Changed
Expand Down
80 changes: 67 additions & 13 deletions specs/v3/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2379,16 +2379,18 @@ paths:
payload:
type: object
description: >-
Optional identity fields to bind into the token. PII fields (id_number,
given_names, last_name, email, phone_number) are validated as plaintext, then
tokenized via the PII vault — the issued JWT carries opaque `pii_`-prefixed
vault token ids, never raw PII. country and id_type stay plaintext in the claim,
and callback_url is replaced by a resolvable `callback_`-prefixed id. Downstream
v3 endpoints inject these fields server-side, overriding any matching fields in
the request body, so identity data bound to the token cannot be altered by the
client. Fields provided here make the corresponding request body fields optional
on downstream endpoints; GET /v3/services/config lists them as
`token_provided_fields`.
Optional identity and consent fields to bind into the token. PII fields
(id_number, given_names, last_name, email, phone_number) are validated, then
replaced with opaque `pii_`-prefixed references — the issued JWT never carries
raw PII. country, id_type and the consent fields stay in the clear, and
callback_url is replaced by a resolvable `callback_`-prefixed id. Downstream v3
endpoints inject these fields server-side, overriding any matching fields in the
request body, so data bound to the token cannot be altered by the client. Fields
provided here make the corresponding request body fields optional on downstream
endpoints; GET /v3/services/config lists them as `token_provided_fields`.
Consent takes the same nested object the v3 entry endpoints accept, and all four
of its fields are required when you send it — an incomplete consent object is
rejected with 400 naming the field that is missing.
properties:
country:
type: string
Expand Down Expand Up @@ -2434,6 +2436,50 @@ paths:
a previously issued token. Overrides the callback_url in the request body of
downstream endpoints.
example: https://example.com/callback
consent:
type: object
description: >-
ISO 27560 consent record, in the same shape the v3 entry endpoints accept.
Optional as a whole; when present, all four fields are required and no other
field is allowed. Injected as `consent` on downstream endpoints, so a
request that carries it need not repeat consent in the body.
required:
- granted
- granted_at
- notice_language
- notice_privacy_policy_url
additionalProperties: false
properties:
granted:
type: boolean
description: >-
Whether the end user granted consent. Must be `true`; any other value is
rejected.
enum:
- true
example: true
granted_at:
type: string
format: date-time
description: >-
When consent was granted, as an ISO 8601 timestamp. Must not be more
than a minute in the future, so a value stamped from your own clock is
fine. Include the timezone — without one the value is read as UTC.
example: '2026-01-01T09:00:00.000Z'
notice_language:
type: string
pattern: ^[A-Za-z]{2}$
description: >-
Two-letter ISO 639-1 code for the language the privacy notice was shown
in. Normalised to uppercase.
example: EN
notice_privacy_policy_url:
type: string
format: uri
description: >-
URL of the privacy notice the end user was shown. Must use the http or
https scheme.
example: https://example.com/privacy-policy
responses:
'200':
description: Success
Expand All @@ -2452,9 +2498,17 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ApiErrorResponse'
example:
status: Bad Request
message: smileid-partner-id header is required.
examples:
missingHeader:
summary: A required header is absent
value:
status: Bad Request
message: smileid-partner-id header is required.
partialConsent:
summary: An incomplete consent object was sent
value:
status: Bad Request
message: Required field 'consent.granted_at' is missing or invalid.
'401':
description: Unauthorized
content:
Expand Down
12 changes: 6 additions & 6 deletions specs/v3/v3-biometric-enrollment-entry.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ info:
At least one of `email` or `phone_number` is required.

Token Payload: Identity fields (given_names, last_name, email, phone_number,
callback_url) can be bound to the authentication token via the token
payload feature at /v3/token (PII fields are stored as opaque vault token
ids, never raw values). When present in the token, these fields are
injected automatically and override any values in the request body. Fields
provided via the token do not need to be repeated in the request body;
GET /v3/services/config lists them as token_provided_fields.
callback_url) and the ISO 27560 consent fields can be bound to the
authentication token via the token payload feature at /v3/token (PII fields
are held as opaque references, never raw values). When present in the token,
these fields are injected automatically and override any values in the
request body. Fields provided via the token do not need to be repeated in
the request body; GET /v3/services/config lists them as token_provided_fields.
tags:
- name: Biometric Enrollment
paths:
Expand Down
13 changes: 7 additions & 6 deletions specs/v3/v3-biometric-kyc-entry.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ info:
At least one of `email` or `phone_number` is required.

Token Payload: Identity fields (country, id_type, id_number, given_names,
last_name, email, phone_number, callback_url) can be bound to the authentication
token via the token payload feature at /v3/token (PII fields are stored
as opaque vault token ids, never raw values). When present in the token,
these fields are injected automatically and override any values in the
request body. Fields provided via the token do not need to be repeated in
the request body; GET /v3/services/config lists them as token_provided_fields.
last_name, email, phone_number, callback_url) and the ISO 27560 consent
fields can be bound to the authentication token via the token payload
feature at /v3/token (PII fields are held as opaque references, never raw
values). When present in the token, these fields are injected automatically
and override any values in the request body. Fields provided via the token
do not need to be repeated in the request body; GET /v3/services/config
lists them as token_provided_fields.
tags:
- name: Biometric KYC
paths:
Expand Down
13 changes: 7 additions & 6 deletions specs/v3/v3-document-verification-entry.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ info:
At least one of `email` or `phone_number` is required.

Token Payload: Identity fields (country, id_type, given_names, last_name,
email, phone_number, callback_url) can be bound to the authentication token via
the token payload feature at /v3/token (PII fields are stored as opaque
vault token ids, never raw values). When present in the token, these
fields are injected automatically and override any values in the request
body. Fields provided via the token do not need to be repeated in the
request body; GET /v3/services/config lists them as token_provided_fields.
email, phone_number, callback_url) and the ISO 27560 consent fields can be
bound to the authentication token via the token payload feature at
/v3/token (PII fields are held as opaque references, never raw values).
When present in the token, these fields are injected automatically and
override any values in the request body. Fields provided via the token do
not need to be repeated in the request body; GET /v3/services/config lists
them as token_provided_fields.
tags:
- name: Document Verification
paths:
Expand Down
13 changes: 7 additions & 6 deletions specs/v3/v3-enhanced-document-verification-entry.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ info:
At least one of `email` or `phone_number` is required.

Token Payload: Identity fields (country, id_type, given_names, last_name,
email, phone_number, callback_url) can be bound to the authentication token via
the token payload feature at /v3/token (PII fields are stored as opaque
vault token ids, never raw values). When present in the token, these
fields are injected automatically and override any values in the request
body. Fields provided via the token do not need to be repeated in the
request body; GET /v3/services/config lists them as token_provided_fields.
email, phone_number, callback_url) and the ISO 27560 consent fields can be
bound to the authentication token via the token payload feature at
/v3/token (PII fields are held as opaque references, never raw values).
When present in the token, these fields are injected automatically and
override any values in the request body. Fields provided via the token do
not need to be repeated in the request body; GET /v3/services/config lists
them as token_provided_fields.
tags:
- name: Enhanced Document Verification
paths:
Expand Down
13 changes: 7 additions & 6 deletions specs/v3/v3-enhanced-kyc-entry.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ info:
At least one of `email` or `phone_number` is required.

Token Payload: Identity fields (country, id_type, id_number, given_names,
last_name, email, phone_number, callback_url) can be bound to the authentication
token via the token payload feature at /v3/token (PII fields are stored
as opaque vault token ids, never raw values). When present in the token,
these fields are injected automatically and override any values in the
request body. Fields provided via the token do not need to be repeated in
the request body; GET /v3/services/config lists them as token_provided_fields.
last_name, email, phone_number, callback_url) and the ISO 27560 consent
fields can be bound to the authentication token via the token payload
feature at /v3/token (PII fields are held as opaque references, never raw
values). When present in the token, these fields are injected automatically
and override any values in the request body. Fields provided via the token
do not need to be repeated in the request body; GET /v3/services/config
lists them as token_provided_fields.
tags:
- name: Enhanced KYC
paths:
Expand Down
79 changes: 68 additions & 11 deletions specs/v3/v3-token.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,21 @@ paths:
payload:
type: object
description: >-
Optional identity fields to bind into the token. PII fields
(id_number, given_names, last_name, email, phone_number) are
validated as plaintext, then tokenized via the PII vault — the
issued JWT carries opaque `pii_`-prefixed vault token ids, never
raw PII. country and id_type stay plaintext in the claim, and
Optional identity and consent fields to bind into the token. PII
fields (id_number, given_names, last_name, email, phone_number)
are validated, then replaced with opaque `pii_`-prefixed
references — the issued JWT never carries raw PII. country,
id_type and the consent fields stay in the clear, and
callback_url is replaced by a resolvable `callback_`-prefixed id.
Downstream v3 endpoints inject these fields server-side,
overriding any matching fields in the request body, so identity
data bound to the token cannot be altered by the client. Fields
overriding any matching fields in the request body, so data
bound to the token cannot be altered by the client. Fields
provided here make the corresponding request body fields optional
on downstream endpoints; GET /v3/services/config lists them as
`token_provided_fields`.
`token_provided_fields`. Consent takes the same nested object
the v3 entry endpoints accept, and all four of its fields are
required when you send it — an incomplete consent object is
rejected with 400 naming the field that is missing.
properties:
country:
type: string
Expand Down Expand Up @@ -139,6 +142,52 @@ paths:
Overrides the callback_url in the request body of
downstream endpoints.
example: https://example.com/callback
consent:
type: object
description: >-
ISO 27560 consent record, in the same shape the v3 entry
endpoints accept. Optional as a whole; when present, all
four fields are required and no other field is allowed.
Injected as `consent` on downstream endpoints, so a
request that carries it need not repeat consent in the
body.
required:
- granted
- granted_at
- notice_language
- notice_privacy_policy_url
additionalProperties: false
properties:
granted:
type: boolean
description: >-
Whether the end user granted consent. Must be
`true`; any other value is rejected.
enum: [true]
example: true
granted_at:
type: string
format: date-time
description: >-
When consent was granted, as an ISO 8601 timestamp.
Must not be more than a minute in the future, so a
value stamped from your own clock is fine. Include
the timezone — without one the value is read as UTC.
example: '2026-01-01T09:00:00.000Z'
Comment on lines +168 to +176

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: format: date-time implies RFC 3339, which mandates a timezone offset, so schema validators and generated clients will reject the timezone-less values the description explicitly allows. Align the schema with the documented behaviour (e.g. drop the strict format or state that the offset is required). [general, importance: 5]

Suggested change
granted_at:
type: string
format: date-time
description: >-
When consent was granted, as an ISO 8601 timestamp.
Must not be more than a minute in the future, so a
value stamped from your own clock is fine. Include
the timezone — without one the value is read as UTC.
example: '2026-01-01T09:00:00.000Z'
granted_at:
type: string
description: >-
When consent was granted, as an ISO 8601 timestamp
(RFC 3339 preferred). Must not be more than a minute
in the future, so a value stamped from your own clock
is fine. Include the timezone — without one the value
is read as UTC.
example: '2026-01-01T09:00:00.000Z'

notice_language:
type: string
pattern: '^[A-Za-z]{2}$'
description: >-
Two-letter ISO 639-1 code for the language the
privacy notice was shown in. Normalised to uppercase.
example: EN
notice_privacy_policy_url:
type: string
format: uri
description: >-
URL of the privacy notice the end user was shown.
Must use the http or https scheme.
example: https://example.com/privacy-policy
responses:
'200':
description: Success
Expand All @@ -157,9 +206,17 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ApiErrorResponse'
example:
status: Bad Request
message: 'smileid-partner-id header is required.'
examples:
missingHeader:
summary: A required header is absent
value:
status: Bad Request
message: 'smileid-partner-id header is required.'
partialConsent:
summary: An incomplete consent object was sent
value:
status: Bad Request
message: "Required field 'consent.granted_at' is missing or invalid."
'401':
description: Unauthorized
content:
Expand Down
Loading