LegalTalentFlowView
Callbacks
There is no error callback. Errors during the flow (expired token, network loss, rejected upload) are shown to the applicant inside the flow with a retry where it makes sense.
KYCSession
The session passed toonComplete. Useful fields:
To get the decision, read the session on your backend by
session_id.
Errors
The headless client throwsLegalTalentError. Every error exposes a stable code:
Zero-retention sessions add
singleSubmitCode; see Zero-retention errors.
Models
Available from v0.3.0.
LegalTalentClient returns (KYCSession, KYCWorkflow, KYCWorkflowStep, KYCStepData, KYCFormField, KYCBranding, KYCIdentityDocumentPolicy, the OTP, terms-of-service, subsession, upload, clip, liveness, extraction and NFC results, the single-submit result) and everything it takes (CreateSubsessionInput, ConsentDocumentInput, IdvNetCaptureEvidence, KYCNfcSubmission, KYCSingleSubmission) is a plain domain type: no Codable conformance on iOS, no @Serializable on Android. The client decodes every response and encodes every request; the wire shape is not part of the public API. The only serializable public type is the JSON primitive, JSONValue / JsonValue.
Three request-body accessors stay public and return exactly what the client sends: KYCNfcSubmission.body (the nfc/submit body), KYCSingleSubmission.body() / encodedBody() (the single-submit body, as a map or as bytes) and IdvNetCaptureEvidence.formData (iOS) / toFormData() (Android) (the idvnet_capture block of a document step’s form data). If you persisted one of these models yourself, keep your own serializable copy of the fields you need.
Unknown values never fail a response. A step type this SDK version does not know is KYCStepType.unknown(rawValue) on iOS and KYCStepType.UNKNOWN on Android, with the wire value on KYCWorkflowStep.type; the flow renders an “unsupported step” screen. A submission mode it does not know is KYCSessionSubmission.Mode.unknown(rawValue) / Mode.Unknown(rawValue). Rendered strings are trimmed and blank ones become nil / null; a link that is not an absolute URL is dropped; submission limits fall back to the contract defaults.
Environments
A token only works against the environment where the session was created. From v0.3.0 the default is
production; name dev or staging explicitly while integrating against them. Up to 0.2.0 the default was dev.
Upgrading to 0.3.0
0.3.0 is a breaking release on both platforms. An app that usesLegalTalentFlowView with the parameters above and reads KYCSession in onComplete needs no code change except naming its environment (item 3). Headless integrations should read all four items.
1
The core module exposes only its documented surface
Everything in
LegalTalentCore / legaltalent-core that is not on this site, in INTEGRATION.md, or reachable from a LegalTalentClient signature is no longer public: document forensics and side validation, identity-document stages, rules and selection, phone-number parsing, the locale resolver and the localized* text helpers, the device-signal trackers and summarisers, the anti-spoof / depth-gate / light-challenge algorithms, the on-device model URLs of KYCEnvironment, UploadInitResult, CaptureClipInitResult and, on Android, the SDK headers interceptor. The full list is in the v0.3.0 release notes.How you notice: a compile error (“cannot find in scope” / “inaccessible due to internal protection level” on iOS, “unresolved reference” or an opt-in error naming LegalTalentInternalApi on Android).What to do: nothing if you did not use them. If a custom UI over LegalTalentClient needs one of these helpers, tell us which; it is documented and made public again. @_spi(LegalTalentInternal) / @LegalTalentInternalApi are for the SDK’s own modules and carry no compatibility promise.2
Models carry no serialization
The models the client returns and takes are domain types (see Models). Names, fields, initializers and constructors are unchanged. Gone: on iOS, the
Codable / Decodable / Encodable conformance of the session, workflow, step, form-field, OTP, terms, subsession, upload, clip, liveness, extraction, branding, identity-policy, NFC and single-submit types; on Android, the serializer() / Companion.serializer() / $serializer members of the same types plus LegalTalentTosOptions and LegalTalentLivenessConfiguration, the public serializer classes (KYCBrandingSerializer, KYCFormFieldSerializer, KYCSingleSubmitResultSerializer, …) and the fromJson companions of KYCNfcConfig, KYCNfcChallenge and KYCNfcAccessKey.How you notice: a compile error where you passed one of these types to JSONEncoder / JSONDecoder, Json.encodeToString / Json.decodeFromString, or named its serializer().What to do: let the client decode the API. If you stored a model yourself, write your own serializable copy of the fields you need; the fields are unchanged. KYCNfcSubmission.body, KYCSingleSubmission.body() / encodedBody() and IdvNetCaptureEvidence.formData / toFormData() still give you the exact request bodies.3
The default environment is production
Every entry point that takes an
environment (LegalTalentFlowView, LegalTalentClient, LegalTalentFlowController, the standalone capture screens, NfcCaptureView) defaults to production; up to 0.2.0 it was dev.How you notice: no compile error. An app that never named its environment now talks to https://kyc.legaltalent.ai and downloads the on-device models from the production host; a session created on dev answers 404.What to do: name the environment explicitly wherever you create a flow or a client, aligned with the backend that created the session. An app that already does so sees no change.4
New error code: contractError / CONTRACT_ERROR
LegalTalentError.contractViolation(endpoint:field:) / LegalTalentError.ContractViolation(endpoint, field) is a new case with the new code contractError / CONTRACT_ERROR. A response the SDK used to reject as unknown / UNKNOWN because a required field was missing is now this error, naming the endpoint and the field; a blank identifier, a relative required link or an NFC challenge that is not base64 are now this error too.How you notice: an exhaustive switch over LegalTalentError or LegalTalentErrorCode without a default (iOS), or an exhaustive when expression (Android), stops compiling. At runtime, contractError where you handled unknown.What to do: add the case and treat it like unknown: retry, then report it with the session ID and the endpoint and field it names.Versioning
One SemVer for both platforms: tagv1.2.3 is SPM from: "1.2.3" and Maven 1.2.3. Published versions are immutable; fixes ship as a new patch version. Production apps must not consume -SNAPSHOT builds.