> ## 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.

# Lifecycle events

> Subscribe to MicroSurvey lifecycle events to wire analytics, debugging, and side effects.

The SDK emits 10 lifecycle events. Subscribe with
`MicroSurvey.on(name, listener)`; the call returns an unsubscribe
function.

```tsx theme={null}
const off = MicroSurvey.on("response_submitted", ({ surveyId, responseId }) => {
  analytics.track("survey_response_submitted", { surveyId, responseId });
});
// when you no longer need the listener:
off();
```

## Event matrix

| Event                | Payload                     | When                                                |
| -------------------- | --------------------------- | --------------------------------------------------- |
| `initialized`        | `{ apiUrl }`                | `init()` finished                                   |
| `survey_shown`       | `{ surveyId }`              | Modal mounted, first question rendered              |
| `survey_dismissed`   | `{ surveyId }`              | User tapped close (no response submitted)           |
| `survey_completed`   | `{ surveyId }`              | Final question submitted, modal closing             |
| `response_submitted` | `{ surveyId, responseId }`  | Server accepted the response                        |
| `response_queued`    | `{ surveyId, queueLength }` | Network failed, response saved to AsyncStorage      |
| `response_failed`    | `{ surveyId, reason }`      | Server rejected with a 4xx (validation, plan limit) |
| `screen_tracked`     | `{ screenName }`            | A new screen path was recorded                      |
| `screen_map_flushed` | `{ screens }`               | The 60s timer flushed accumulated screen visits     |
| `error`              | `{ where, message }`        | Any SDK error not caught by a more specific event   |

## When events fire

```mermaid theme={null}
sequenceDiagram
  participant App
  participant SDK
  participant API

  App->>SDK: init()
  SDK-->>App: initialized
  App->>SDK: identify()
  App->>SDK: trigger("checkout_completed")
  SDK->>API: POST /v1/sdk/event
  API-->>SDK: { survey }
  SDK-->>App: survey_shown
  Note over App: User answers questions
  SDK->>API: POST /v1/sdk/response
  API-->>SDK: { responseId }
  SDK-->>App: survey_completed + response_submitted
```

## Common patterns

### Fan out to your own analytics

```tsx theme={null}
useEffect(() => {
  const offShown = MicroSurvey.on("survey_shown", (p) => {
    analytics.track("insito_survey_shown", p);
  });
  const offDone = MicroSurvey.on("response_submitted", (p) => {
    analytics.track("insito_response_submitted", p);
  });
  return () => {
    offShown();
    offDone();
  };
}, []);
```

### Surface errors in dev

```tsx theme={null}
useEffect(() => {
  if (!__DEV__) return;
  return MicroSurvey.on("error", ({ where, message }) => {
    console.error(`[insito:${where}] ${message}`);
  });
}, []);
```

### Show a thank-you toast

```tsx theme={null}
useEffect(() => {
  return MicroSurvey.on("response_submitted", () => {
    Toast.show("Thanks for the feedback!");
  });
}, []);
```

### Differentiate online vs queued

```tsx theme={null}
useEffect(() => {
  const offSubmitted = MicroSurvey.on("response_submitted", (p) => {
    analytics.track("survey_submitted_online", p);
  });
  const offQueued = MicroSurvey.on("response_queued", (p) => {
    analytics.track("survey_submitted_offline", p);
  });
  return () => {
    offSubmitted();
    offQueued();
  };
}, []);
```

## Memory model

Listeners are held by reference. The SDK doesn't weak-ref them; if
you don't call the returned unsubscribe, the listener (and anything
it closes over) lives for the lifetime of the app. Always unsubscribe
in cleanup.

```tsx theme={null}
// Bad — leaks on every mount/unmount cycle
useEffect(() => {
  MicroSurvey.on("survey_shown", track);
}, []);

// Good — clean teardown
useEffect(() => MicroSurvey.on("survey_shown", track), []);
```
