React Native Representations#
The Curity HAAPI React Native SDK delivers every HAAPI response as a fully-typed TypeScript value — host apps never deal with raw JSON. This page covers the HaapiResponse discriminated union: the step types you switch on, the action shapes you submit, and the form-field models you render.
The same model hierarchy exists on iOS and Android — see iOS Representations and Android Representations for the per-platform shape. Each platform exposes the same 14 step types, action shapes, and problem variants through its own type system: Swift uses an enum (HaapiResult) with protocol-conforming representation types, Kotlin uses a sealed HaapiResponse with HaapiRepresentation interface and ProblemRepresentation siblings, and React Native uses a TypeScript discriminated union. This page is the React Native narrative reference.
Equivalent type names by platform#
A quick map for cross-platform readers. The names differ but the model is the same.
| Concept | React Native | iOS (Swift) | Android (Kotlin) |
|---|---|---|---|
| Top-level response wrapper | HaapiResponse (discriminated on responseCategory) | HaapiResult (.representation / .problem / .error) | HaapiResponse (sealed; HaapiRepresentation / ProblemRepresentation / ClientOperationStep siblings) |
| Step-shaped representation | HaapiRepresentation (discriminated on stepType) | HaapiRepresentation (protocol; per-step structs conform) | HaapiRepresentation (interface; per-step classes implement) |
| Problem-shaped representation | ProblemRepresentation (discriminated on problemKind) | Problem (protocol; InvalidInputProblem, AuthorizationProblem conform) | ProblemRepresentation (sealed; subclasses) |
| Step variants (14) | AuthenticatorSelectorStep, InteractiveFormStep, PollingStep, … | Same names, Swift-idiom | Same names, Kotlin-idiom |
| Action variants | FormAction, SelectorAction, ClientOperationAction | Same names, Swift-idiom | Same names + ClientOperationStep siblings |
| Form-field variants | TextFormField, PasswordFormField, SelectFormField, … | Same names, Swift-idiom | FormField.Text, FormField.Password, … (nested) |
For the per-platform narrative, see iOS Representations or Android Representations . For the full type signatures, follow the autodoc links from the reference pages: iOS Reference (DocC for IdsvrHaapiSdk), Android Reference (KDoc for identityserver.haapi.android.sdk).
The rest of this page is the React Native narrative — discriminated-union shape, switching patterns, rendering helpers.
SDK-thrown errors are separate. Network failures, attestation failures, and bridge invariants reject the Promise with a typed HaapiError instead of resolving with a HaapiResponse. Catch them with try/catch + isHaapiError(e). See Error Handling .
Response Hierarchy#
Every call to start(), submitForm(), or followLink() returns a HaapiResponse. It is a discriminated union on responseCategory:
| Variant | When it surfaces | Key field |
|---|---|---|
HaapiRepresentationResponse (responseCategory: 'representation') | The flow continues with another step | representation: HaapiRepresentation |
HaapiProblemResponse (responseCategory: 'problem') | The server rejected the request (RFC 7807) | problem: ProblemRepresentation |
Branch on responseCategory first; then narrow further on representation.stepType or problem.problemKind.
Step Types#
HaapiRepresentation is a discriminated union on stepType with 14 variants. The StepType enum exposes each value:
Common fields#
Every step shares these base fields:
| Field | Type | Description |
|---|---|---|
stepType | StepType | Discriminator (14 values) |
type | RepresentationType | HAAPI representation type (8 values) |
metadata | Metadata? | Template area and view name |
actions | Action[] | Available actions for this step |
links | Link[] | Navigation links (e.g., “forgot password”) |
messages | UserMessage[] | User-facing messages to display |
The 14 step types#
Grouped by purpose:
| Group | Step type | Extra fields |
|---|---|---|
| Interactive | AuthenticatorSelector | title, authenticators[] |
InteractiveForm | properties? | |
UserConsent | — | |
| Flow control | Redirection | redirectAction |
Polling | mainAction, cancelAction?, pollingProperties | |
ContinueSame | — | |
| OAuth | OAuthAuthorizationResponse | oauthProperties (carries code) |
| Client operation | ExternalBrowserClientOperation | — |
BankIdClientOperation | activationLink? | |
EncapClientOperation | — | |
WebAuthnRegistrationClientOperation | — | |
WebAuthnAuthenticationClientOperation | — | |
GenericClientOperation | — | |
| Fallback | GenericRepresentation | properties? |
Switching on stepType#
import { StepType, ActionType } from 'identityserver.haapi.reactnative.sdk'
switch (response.representation.stepType) {
case StepType.AuthenticatorSelector:
// Narrows to AuthenticatorSelectorStep
for (const auth of response.representation.authenticators) {
// auth.title.literal, auth.type, auth.action (a FormAction)
}
break
case StepType.InteractiveForm:
// Narrows to InteractiveFormStep
const formAction = response.representation.actions.find(
(a) => a.actionType === ActionType.Form
)
// Render formAction.model.fields as a React form
break
case StepType.Polling:
// Narrows to PollingStep
// Submit response.representation.mainAction to poll;
// submit cancelAction to abort.
break
case StepType.OAuthAuthorizationResponse:
// Flow complete — extract code and exchange for tokens.
const code = response.representation.oauthProperties.code
break
// …other step types
}
Actions#
Actions represent operations the user can perform. Discriminated on actionType:
| Variant | actionType | Carries | When to use |
|---|---|---|---|
FormAction | Form | model: FormActionModel | The most common action — render fields, submit values |
SelectorAction | Selector | options: Action[] | Server provides a choice (e.g., device selector); each option is itself an Action |
ClientOperationAction | ClientOperation | model: ClientOperationActionModel | External handling required (BankID, WebAuthn, browser launch) |
Every action also carries:
| Field | Type | Description |
|---|---|---|
kind | ActionKind | Semantic meaning: Login, Cancel, Redirect, Poll, etc. (17 values) |
title | Message? | Display title for buttons / labels |
FormAction#
Submitting a form is the SDK’s primary write operation:
const formAction = action as FormAction
const submitValues: Record<string, unknown> = {
[formAction.model.fields[0].name]: 'user@example.com',
[formAction.model.fields[1].name]: 'secret',
}
const next = await accessor.haapiManager.submitForm(formAction, submitValues)
submitForm’s parameters accept any JSON-serialisable value (string, number, boolean, null, nested objects, arrays) — matching the native iOS and Android signatures. For GET form actions, the native side still requires string-only values. See HAAPI Flow for the full parameter-type semantics across platforms.
The FormActionModel carries:
| Field | Type | Description |
|---|---|---|
fields | FormField[] | Form fields to render |
method | string | HTTP method (e.g., "POST") |
href | string | Target URI |
actionTitle | Message? | Submit button text |
ClientOperationAction#
Six sub-types, each with its own model fields, discriminated on clientOperationType: ExternalBrowser, BankId, Encap, WebAuthnRegistration, WebAuthnAuthentication, Generic. Each model includes continueActions and errorActions arrays for post-operation flow.
Form Fields#
Fields are a discriminated union on fieldType with 7 variants.
Common fields#
| Field | Type | Description |
|---|---|---|
fieldType | FormFieldType | Discriminator (7 values) |
name | string | Parameter key for submission |
value | string? | Current / default value |
label | Message? | Display label |
placeholder | Message? | Placeholder text |
isRequired | boolean | Whether the field is required |
Rendering guide#
fieldType | React Native element | Notes |
|---|---|---|
Hidden | none | Include value in submit params automatically — don’t render |
Text | <TextInput> | Inspect kind for keyboard type (email, tel, etc.) |
Username | <TextInput> | autoCapitalize="none" |
Password | <TextInput> | secureTextEntry={true} |
Select | Picker or buttons | Render options[] as choices |
Checkbox | <Switch> | Respect readOnly flag |
Context | none | Hidden context data (e.g., WebAuthn challenge) — don’t render |
A helper to collect visible (non-hidden, non-context) fields when rendering a form:
import { ActionType, FormFieldType } from 'identityserver.haapi.reactnative.sdk'
import type { FormField, HaapiRepresentation } from 'identityserver.haapi.reactnative.sdk'
function collectVisibleFields(step: HaapiRepresentation): FormField[] {
const fields: FormField[] = []
for (const action of step.actions) {
if (action.actionType === ActionType.Form) {
for (const field of action.model.fields) {
if (
field.fieldType !== FormFieldType.Hidden &&
field.fieldType !== FormFieldType.Context
) {
fields.push(field)
}
}
}
}
return fields
}
Problems#
Problem responses follow RFC 7807, discriminated on problemKind:
| Variant | problemKind | Extra fields |
|---|---|---|
Problem | base | (base only) |
InvalidInputProblem | invalidInput | invalidFields[] (each: name, reason?, detail: Message), errorDescription? |
AuthorizationProblem | authorization | error, errorDescription? |
InvalidInputProblem.invalidFields[] is the right hook for showing field-level validation errors inline in your React form.
Token Responses#
fetchAccessToken, refreshAccessToken, and the revoke methods all return a TokenResponse (a successful Promise resolution — not an error). Discriminated on responseType:
| Variant | responseType | Fields |
|---|---|---|
SuccessfulTokenResponse | success | accessToken, tokenType?, scope?, expiresIn, refreshToken?, idToken? |
ErrorTokenResponse | error | error, errorDescription?, errorUri? |
See OAuthTokenManager for the full lifecycle, and Error Handling for the difference between RFC-6749 OAuth errors (values) and SDK-thrown errors (Promise rejections).
Links#
Each Link carries:
| Field | Type | Description |
|---|---|---|
href | string | Target URI |
rel | string | Relationship type (e.g., forgot-password) |
title | Message? | Display text |
Render link sets alongside the main form — typically rendered as secondary buttons or text links. Submit a link via accessor.haapiManager.followLink(link) to navigate.
Related: HAAPI Flow · OAuthTokenManager · Error Handling · React Native SDK