Reference
Changelog
Notable changes to the ThirdFactor Obsidian API, SDKs, and hosted flows.
Dated, most-recent-first. Breaking changes are called out explicitly; when in
doubt, pin workflow_id and branch on stable decisions rather than raw statuses.
How to read this changelog
Scan the headline
Each entry opens with what changed and why it matters, before the field-level detail. If nothing in the headline touches your integration, you can usually skip the rest of the entry.
Check for a breaking-change callout
A <Warning> in an entry means existing integrations need action — a payload
shape changed, a field was removed, or a default behavior flipped. An entry
with no warning is additive: new capability, nothing to change on your side.
Cross-reference the linked pages
Entries link to the concept/reference page that now documents the feature in full, rather than duplicating the whole spec inline here. Use the changelog to find out that something changed, and the linked page to find out how it works.
2026-07-11 — ThirdFactor Verify SDKs and NFC
The big one: ThirdFactor Verify — a built-in KYC engine — and a set of native client SDKs, so no external verification SDK is required.
ThirdFactor Verify engine (/v3). Document verification, passive / colour-flash /
3D-action liveness, and face match run inside Obsidian. Design workflows in
Console → Config → KYC Workflows; manage sessions and identities in
Console → Verifications and Console → Identities.
POST /v3/session/creates a hosted verification session and returns aurlon the tenant flow domain. The server enforces the configured liveness method — it cannot be downgraded client-side.Idempotency-Keyon session create makes retries safe and never double-charges credits.- Read and manage sessions:
GET /v3/session/,GET /v3/session/<id>/,GET /v3/session/<id>/decision/, plusupdate-status,delete,logs,checklist,tags, andgenerate-pdf. - Standalone tools mirror the console Manual Tools:
aml-check,face-search,signature-verify,signature-search(beta),signature-enroll, anddocument-extract.
Client SDKs. Native SDKs that open the flow and return an advisory result:
@thirdfactor/web
ThirdFactor.verify({ url }), with a server-only @thirdfactor/web/server helper.ThirdFactorKYC (iOS)
thirdfactor-kyc (Android)
thirdfactor_kyc (Flutter)
NFC. Native NFC reader modules on iOS, Android, and Flutter read the document chip; a bidirectional bridge exposes capability/command negotiation, and the backend accepts chip data via an NFC flow step. See the NFC deep-dive.
KYC webhooks. Terminal sessions emit signed webhook events —
identity.kyc.session.approved, .declined, .review, .expired — through the
same signed delivery pipeline as application events.
Warning
KYC session webhook payloads are flat: decision, status, vendor_data,
session_id, and the rest are top-level fields, with no nested session
object. Application webhooks keep the versioned { payload_version, application, form_data, sdk_response, blocklist_match } envelope. If you built a webhook
handler before this release that assumed every event had a nested
application object, it needs a branch on event_type to route KYC session
events differently. See webhooks.
Hosted flows. A hosted session whose flow contains an sdk step runs
ThirdFactor Verify inline as a single continuous flow — no external
verification vendor and no hand-off out of the flow.
Info
This is the starting point for the public changelog. Subsequent releases will be added here, newest first, with any breaking changes flagged.
Versioning and stability
Obsidian's public contract is layered so that additive changes never break a well-written integration:
- Stable decisions (
approved,rejected/declined,manual_review/in_review,in_progress,abandoned) are the long-term contract. New raw statuses can appear for workflow diagnostics without changing this set — see decisions. workflow_idpins which modules a session runs. Leaving it unset uses the tenant default, which an operator can change in the console at any time — pin it explicitly if your integration depends on a specific module set.- Webhook envelopes are additive-only: new fields can appear, but existing
fields keep their meaning. The
payload_versionon application events exists specifically so a schema change, if one is ever needed, is detectable rather than silent. - Unknown values are treated conservatively. An unrecognised terminal
status should be handled the same way the SDKs handle it internally: as
in_review, not as a pass. That one rule keeps forward-compatible code working across additive releases without a docs update on your side.