> For the complete documentation index, see [llms.txt](https://docs.sudoplatform.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sudoplatform.com/~/revisions/U8P5YQbTWlABRqHUlUfP/guides/privacy-interaction/manage-virtual-presences.md).

# Manage Virtual Presences

Once connected, the platform service scans the account to discover data holders and perform privacy analyses.

### Connecting a Virtual Presence <a href="#connecting-a-virtual-presence" id="connecting-a-virtual-presence"></a>

A virtual presence can be connected using either an OAuth authorization code (from a user-initiated login flow) or a pre-obtained refresh token.

#### Connect with Authorization Code <a href="#connect-with-authorization-code" id="connect-with-authorization-code"></a>

Use this method when your application has completed an OAuth flow and received an authorization code from the provider.

{% tabs %}
{% tab title="Typescript" %}

```typescript
try {
  const virtualPresence = await privacyInteractionClient.connectVirtualPresenceWithAuthCode(
    authCode,
  )
  // The virtual presence is now connected.
  // `virtualPresence.state` will be `CONNECTED` or `SCANNING`.
} catch (error) {
  // Handle/notify user of errors
}
```

{% endtab %}
{% endtabs %}

#### Connect with Refresh Token <a href="#connect-with-refresh-token" id="connect-with-refresh-token"></a>

Use this method when your application already holds a valid refresh token for the provider.

{% tabs %}
{% tab title="First Tab" %}

```typescript
try {
  const virtualPresence = await privacyInteractionClient.connectVirtualPresenceWithRefreshToken({
    refreshToken: 'refresh-token-value',
    providerIdentity: 'user@example.com',
    scopes: ['https://www.googleapis.com/auth/gmail.readonly'],
    expiresInEpochMs: 1700000000000, // optional
  })
  // The virtual presence is now connected.
} catch (error) {
  // Handle/notify user of errors
}
```

{% endtab %}
{% endtabs %}

**Input Parameters:**

| Parameter          | Type      | Required | Description                                                      |
| ------------------ | --------- | -------- | ---------------------------------------------------------------- |
| `refreshToken`     | string    | Yes      | The refresh token value.                                         |
| `providerIdentity` | string    | Yes      | The identity associated with the provider (e.g., email address). |
| `scopes`           | string\[] | No       | OAuth scopes associated with the token.                          |
| `expiresInEpochMs` | number    | No       | Token expiration time in milliseconds since epoch.               |

### Disconnecting a Virtual Presence <a href="#disconnecting-a-virtual-presence" id="disconnecting-a-virtual-presence"></a>

To disconnect a virtual presence and stop it from being scanned, call `disconnectVirtualPresence` with the virtual presence's unique identifier.

When a virtual presence is disconnected, its state will transition to `INACTIVE`. Any existing data holders and analysis results associated with the virtual presence will remain accessible.

{% tabs %}
{% tab title="First Tab" %}

```typescript
try {
  const virtualPresence = await privacyInteractionClient.disconnectVirtualPresence(
    virtualPresenceId,
  )
  // The virtual presence is now disconnected.
  // `virtualPresence.state` will be `INACTIVE`.
} catch (error) {
  // Handle/notify user of errors
}
```

{% endtab %}
{% endtabs %}

### Listing Virtual Presences <a href="#listing-virtual-presences" id="listing-virtual-presences"></a>

To retrieve all virtual presences for the signed-in user, use the `listVirtualPresences` method. Results are paginated.

A call to `listVirtualPresences` returns a `ListOutput` object containing a list of matching `items` and a `nextToken` to support pagination. If no results are found, the result will contain empty items. Always check the value of the returned `nextToken`—there are no more results to retrieve when `nextToken` is undefined.

{% tabs %}
{% tab title="Typescript" %}

```typescript
try {
  const listOutput = await privacyInteractionClient.listVirtualPresences({
    limit: 20,
    nextToken: undefined,
  })
  // `listOutput.items` contains the virtual presences.
  // Page through results if `listOutput.nextToken` is defined.
} catch (error) {
  // Handle/notify user of errors
}
```

{% endtab %}
{% endtabs %}

**Input Parameters:**

| Parameter   | Type   | Required | Description                                                      |
| ----------- | ------ | -------- | ---------------------------------------------------------------- |
| `limit`     | number | No       | Maximum number of items to return. Will be defaulted if omitted. |
| `nextToken` | string | No       | A pagination token from a previous call.                         |

### Virtual Presence States <a href="#virtual-presence-states" id="virtual-presence-states"></a>

A virtual presence transitions through the following states:

| State          | Description                                                                                                                                                                                                                        |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CONNECTED`    | The virtual presence is active and connected to the provider.                                                                                                                                                                      |
| `SCANNING`     | The virtual presence is currently being scanned for data holders.                                                                                                                                                                  |
| `NEEDS_REAUTH` | The virtual presence requires re-authentication with the provider. This will happen automatically when the refresh token expires, or when the user explicitly disconnects the Privacy Interaction application from their provider. |
| `ERROR`        | The virtual presence encountered an error and is in a failed state.                                                                                                                                                                |
| `INACTIVE`     | The virtual presence has been disconnected and is no longer active.                                                                                                                                                                |

When a virtual presence enters the `NEEDS_REAUTH` state, your application should prompt the user to re-authenticate with the provider and call `connectVirtualPresenceWithAuthCode` or `connectVirtualPresenceWithRefreshToken` again.

### Subscribing to Virtual Presence Updates <a href="#subscribing-to-virtual-presence-updates" id="subscribing-to-virtual-presence-updates"></a>

To receive real-time notifications when a virtual presence changes state, see [Subscriptions](file:///Users/jkowald/source/repos/sudo-privacy-interaction-js/docs/guides/privacy-interaction/subscriptions.md).
