> ## Documentation Index
> Fetch the complete documentation index at: https://docs.insito.app/llms.txt
> Use this file to discover all available pages before exploring further.

# API reference

> Every method, type, and lifecycle event exported by @insito/react-native.

The package has a small surface — one singleton (`MicroSurvey`), one
React provider (`<InsitoProvider>`), one hook (`useInsito`), and one
navigation helper (`useInsitoScreenTracking`), plus theme/label helpers.

## Imports

```tsx theme={null}
import {
  MicroSurvey,
  InsitoProvider,
  useInsito,
  useInsitoScreenTracking,
  resolveTheme,
  themePresets,
  SDK_DEFAULT_LABELS,
  resolveLabels,
} from "@insito/react-native";

import type {
  InsitoConfig,
  InsitoVariableDeclaration,
  InsitoTheme,
  IdentifyArgs,
  InsitoEvent,
  InsitoEventName,
  InsitoEventListener,
  ActiveSurvey,
  Answer,
  SurveyQuestion,
  SdkState,
  SdkLabels,
  ThemePreset,
  InsitoUser,
  ApiResponse,
  InsitoProviderProps,
  InsitoAppearance,
  SubmitResponseOptions,
  SubmitResponseResult,
} from "@insito/react-native";
```

## `MicroSurvey`

The named-export singleton (`import { MicroSurvey }`). Holds the SDK state
machine and the imperative methods you call from your app.

### `MicroSurvey.init(config)`

Boots the SDK. Call once, as early as possible (module top-level is
fine). Subsequent calls are silently ignored; a console warning is emitted only
when `debug: true` was set on the first successful `init()`.

<ParamField path="config.apiKey" type="string" required>
  Project API key. Format: `proj_xxx`. Throws synchronously if
  malformed.
</ParamField>

<ParamField path="config.apiUrl" type="string" default="https://api.insito.app">
  Override the API base URL — useful for staging environments or
  self-hosted instances. Default points to production.
</ParamField>

<ParamField path="config.requestTimeoutMs" type="number" default="5000">
  Per-request timeout in milliseconds. Lowering this on flaky
  networks will route more responses through the offline queue.
</ParamField>

<ParamField path="config.debug" type="boolean" default="false">
  Toggles internal `console.log` output. Recommended:
  `debug: __DEV__`.
</ParamField>

<ParamField path="config.environment" type="string">
  Optional environment tag (e.g. `"production"`, `"staging"`) sent as device
  metadata and usable in audience filters.
</ParamField>

<ParamField path="config.theme" type="object">
  `{ preset?: 'light' | 'dark' | 'minimal' | 'rounded', overrides?: Partial<InsitoTheme> }`.
  See [Theming](/sdk/react-native/theming).
</ParamField>

<ParamField path="config.labels" type="Partial<SdkLabels>">
  In-code overrides for the built-in UI strings. See
  [Labels](/sdk/react-native/labels).
</ParamField>

<ParamField path="config.events" type="InsitoVariableDeclaration[]">
  Event keys to pre-declare into the registry on the next `identify()`.
</ParamField>

<ParamField path="config.screens" type="InsitoVariableDeclaration[]">
  Screen names to pre-declare into the registry on the next `identify()`.
</ParamField>

```tsx theme={null}
MicroSurvey.init({
  apiKey: "proj_xxx",
  debug: __DEV__,
  environment: "production",
  theme: { preset: "rounded" },
});
```

### `MicroSurvey.identify(args)`

Associates subsequent triggers with a stable user. Cached for 24
hours per `userId` so repeat calls don't hit the network.

<ParamField path="args.userId" type="string" required>
  Stable, unique identifier for your user. Most teams pass their
  database user ID. Do NOT pass an email or anything PII unless
  you've configured PII handling on your account.
</ParamField>

<ParamField path="args.platform" type="string">
  e.g. `"ios"`, `"android"`, `"web"`. Used by analytics for
  platform breakdowns.
</ParamField>

<ParamField path="args.appVersion" type="string">
  Your app's build version, e.g. `"2.7.0"`. Surfaces in the
  dashboard so you can correlate feedback with releases.
</ParamField>

<ParamField path="args.metadata" type="Record<string, unknown>">
  Free-form device-level key/value pairs. Merged on top of the SDK's
  [auto-captured device metadata](/sdk/react-native/configure#auto-captured-device-metadata)
  — your keys win on a collision.
</ParamField>

<ParamField path="args.properties" type="Record<string, string | number | boolean>">
  Custom, business-level user properties (e.g. `plan: "premium"`,
  `transactionsThisMonth: 14`, `hasLinkedCard: true`). Stored on the respondent
  and discovered into the dashboard
  [User Properties](/dashboard/user-properties) registry, where they become
  type-aware audience filters. Only `string` / `number` / `boolean` values are
  kept. Call `identify()` again whenever a value changes — the API always uses
  the most recent value.
</ParamField>

```tsx theme={null}
await MicroSurvey.identify({
  userId: "auth_4f93k...",
  platform: "ios",
  appVersion: "2.7.0",
  metadata: { cohort: "beta-q2" },
  properties: {
    plan: "premium",
    transactionsThisMonth: 14,
    hasLinkedCard: true,
  },
});
```

<Note>
  Even with no `metadata` or `properties`, every `identify()` auto-captures
  device + lifecycle metadata (`locale`, `timezone`, `osVersion`,
  `sessionCount`, `daysSinceInstall`). See
  [Configure](/sdk/react-native/configure#auto-captured-device-metadata).
</Note>

### `MicroSurvey.trigger(eventName)`

Fires a trigger by name. The server decides whether to show a survey.
`trigger()` is `async` (`Promise<void>`) and sets the state to `loading` while
the request is in flight; the modal appears once the server responds. Fire it
fire-and-forget with `void`.

<ParamField path="eventName" type="string" required>
  Event name configured against a survey in the dashboard (e.g.
  `"checkout_completed"`). Allowed characters are `A–Z a–z 0–9 _`; keys are
  case-sensitive. See [Triggers](/concepts/triggers).
</ParamField>

```tsx theme={null}
void MicroSurvey.trigger("checkout_completed");
```

Guards:

* Not initialised → no-op + debug warning.
* No `identify()` call yet → no-op + debug warning.
* A survey is already active → no-op + debug log.

### `MicroSurvey.submitResponse(surveyId, answers, options?)`

Used internally by the built-in modal. You'd only call this directly
if you're rendering your own question UI.

<ParamField path="surveyId" type="string" required>
  The active survey's ID — usually `MicroSurvey.activeSurvey?.surveyId`.
</ParamField>

<ParamField path="answers" type="Answer[]" required>
  Array of `{ questionId, type, value }`. See [Answer type](#answer)
  below.
</ParamField>

<ParamField path="options" type="SubmitResponseOptions">
  `{ keepModalOpen?: boolean; responseId?: string }`. Pass `responseId` to
  complete an existing partial response.
</ParamField>

Returns `Promise<SubmitResponseResult>`:

```ts theme={null}
type SubmitResponseResult =
  | { status: "success"; responseId: string }
  | { status: "queued" }
  | { status: "failed"; reason: string };
```

### `MicroSurvey.evaluate(reason?, options?)`

Runs the auto-evaluated trigger check (app open, session start, screen visit).
The SDK calls this automatically on identify and screen visits; call it directly
only for custom lifecycle hooks. Returns `Promise<void>`.

### `MicroSurvey.savePartialProgress(surveyId, answers, existingResponseId?)`

Persists in-progress answers for autosave-enabled surveys. Used internally by
the modal as the user advances; returns the partial response id.

### `MicroSurvey.dismissSurvey()`

Closes the active modal without submitting. Emits `survey_dismissed`.
Used by the close button in the built-in UI.

### `MicroSurvey.on(event, listener)` / `MicroSurvey.off(event, listener)`

Subscribe to lifecycle events. `on()` returns an unsubscribe function.

```tsx theme={null}
const off = MicroSurvey.on("response_submitted", ({ surveyId, responseId }) => {
  analytics.track("survey_response_submitted", { surveyId, responseId });
});
// later
off();
```

See [Lifecycle events](/sdk/react-native/events) for the full event
matrix.

### `MicroSurvey.onNavigationStateChange(state)`

Bridges React Navigation v6/v7 state into the screen-map system.
Subscribe in your `NavigationContainer.onStateChange`:

```tsx theme={null}
import { MicroSurvey } from "@insito/react-native";

<NavigationContainer onStateChange={MicroSurvey.onNavigationStateChange}>
  ...
</NavigationContainer>
```

Expo Router users should use `useInsitoScreenTracking()` instead.

### Read-only state

```ts theme={null}
MicroSurvey.state         // 'idle' | 'loading' | 'survey_active' | 'completed'
MicroSurvey.activeSurvey  // ActiveSurvey | null
MicroSurvey.user          // InsitoUser | null
MicroSurvey.theme         // InsitoTheme
MicroSurvey.config        // runtime API settings only, or null
```

`MicroSurvey.config` returns only the runtime API settings (`apiKey`, `apiUrl`,
`requestTimeoutMs`, `debug`, `environment`) — not the `theme`, `labels`,
`events`, or `screens` you passed to `init()`.

## React layer

### `<InsitoProvider>`

Renders the survey bottom sheet. Wrap your app inside one (under a
`GestureHandlerRootView`). Children render normally; the survey sheet mounts on
top via `@gorhom/bottom-sheet`.

```tsx theme={null}
<InsitoProvider>
  <App />
</InsitoProvider>
```

Optional `appearance` prop drives the light/dark scheme for
`themeMode: "auto"` surveys. Defaults to `"system"` (follow the device); pass
`"light"` / `"dark"` to mirror your app's own theme. See
[Theming](/sdk/react-native/theming#follow-your-apps-theme).

```tsx theme={null}
<InsitoProvider appearance={isDark ? "dark" : "light"}>
  <App />
</InsitoProvider>
```

### `useInsito()`

Hook that returns reactive state:
`{ activeSurvey, dismissSurvey, theme, sdkState, labels }`. Re-renders when any
of them change. Throws if called outside `<InsitoProvider>`.

```tsx theme={null}
function FeedbackButton() {
  const { sdkState } = useInsito();
  const disabled = sdkState === "loading" || sdkState === "survey_active";
  return (
    <Button
      disabled={disabled}
      onPress={() => MicroSurvey.trigger("manual_feedback")}
    />
  );
}
```

### `useInsitoScreenTracking()`

Auto-tracks screen visits for Expo Router apps. Call it in your root
layout — no arguments needed.

```tsx theme={null}
import { useInsitoScreenTracking } from "@insito/react-native";

export default function RootLayout() {
  useInsitoScreenTracking();
  return <Stack />;
}
```

See [Screen tracking](/sdk/react-native/screen-tracking) for the
React Navigation alternative and the data model.

## Theme helpers

### `resolveTheme(preset, overrides?)`

Builds an `InsitoTheme` from a preset name (`'light' | 'dark' | 'minimal' | 'rounded'`)
plus optional overrides. Useful if you want to preview a theme
outside the SDK.

### `themePresets`

The raw preset map: `{ light, dark, minimal, rounded }`. Each entry is
a complete `InsitoTheme`. Use this if you want to start from a preset
and tweak it deeply.

## Types

### `Answer`

```ts theme={null}
interface Answer {
  questionId: string;
  type: "nps" | "rating" | "multiple_choice" | "open_text";
  value: string | number | string[];
}
```

* `nps`: `value` is a number 0–10.
* `rating`: `value` is a number 1–5.
* `multiple_choice`: `value` is a string (single-select) or string\[]
  (multi-select).
* `open_text`: `value` is a string.

### `SdkState`

```ts theme={null}
type SdkState = "idle" | "loading" | "survey_active" | "completed";
```

State machine:

* `idle` → user can fire `trigger()`.
* `loading` → trigger in flight to the server.
* `survey_active` → modal is on screen.
* `completed` → response submitted, modal closed (transient).

### `InsitoEventName`

```ts theme={null}
type InsitoEventName =
  | "initialized"
  | "survey_shown"
  | "survey_dismissed"
  | "survey_completed"
  | "response_submitted"
  | "response_queued"
  | "response_failed"
  | "screen_tracked"
  | "screen_map_flushed"
  | "error";
```

See [Lifecycle events](/sdk/react-native/events) for the payload of
each.
