# Members still being verified

> What a member sees, what your app receives, and what your app should do when a member has not finished STX verification.

Source: https://docs.stxapp.io/oauth/members-being-verified/

> **Availability.** Available on US demo now. Live access is coming soon in the US and Ontario. See [Environments](https://docs.stxapp.io/environments/).

STX verifies a member before they can trade. Until that is finished your app gets no new tokens for them, and wherever STX issues tokens, on the connect redirect and at the token endpoint, it gives the same answer: `account_pending`. The one exception is a `prompt=none` request from an app that has no connection to the member yet, which answers `consent_required` whatever the state of their account.

Your app has two things to tell apart:

- **Not finished verifying** (`account_pending`): show a message such as "Finish verifying your STX account". If your app already holds tokens for the member, keep them: they work again once the member is verified. If it holds none yet, there is nothing to keep; let them connect again later.
- **Not connected** (anything else): ask the user to connect again.

An API call does not say which of the two it is: it answers a plain `401`. The refresh you try next does; see [When your app already holds tokens](#when-your-app-already-holds-tokens).

This applies whichever way your app [adds STX accounts](/oauth/#start-from-where-you-are).

## When the member connects or logs in

Your app receives the answer at your `redirect_uri`, with the `state` you sent. No `code` is issued, so there are no tokens.

| What happened | The member sees | Your app receives | What your app should do |
| --- | --- | --- | --- |
| They have not finished verification, and your app has no connection to them yet. It does not matter whether they just logged in on STX or were already logged in | An STX page with your app's name saying the account is being verified, with a button back to your app | `error=account_pending`, when they press the button | Show "finish verifying". Let them connect again later |
| They have not finished verification, and your app is already connected to them. This covers a [silent re-authorization](/oauth/authorization-flow/#returning-members-silent-re-authorization) and a request for more scopes | No STX page; they come straight back to your app | `error=account_pending` | The same. Keep the connection |
| You sent `prompt=none`, they are signed in to STX, and your app has no connection to them | No STX page | `error=consent_required`, whatever the state of their account | Send the request again without `prompt=none` |
| They pressed **Deny** | The consent screen | `error=access_denied` | Show your not-connected state |
| They cannot use STX right now | No STX page | `error=access_denied` | Show your not-connected state |

`account_pending` comes with a description:

```
<redirect_uri>?error=account_pending&error_description=The+member%27s+STX+account+is+awaiting+verification.&state=<the state you sent>
```

A member who closes the STX page instead of pressing the button never reaches your callback. Treat a connect that was started and not finished as abandoned.

## When your app already holds tokens

A member your app is connected to can fall back to "not finished verifying". Their tokens stop working until they finish, and work again afterwards.

| Your call | Answer | What your app should do |
| --- | --- | --- |
| An API call with their access token | `401` | Try a refresh; its answer tells you which case this is |
| A refresh, while the member has not finished verification | `400` with `error` `invalid_grant` and `error_reason` `account_pending` | **Keep the stored tokens.** Show "finish verifying". The same refresh token works once the member is verified |
| A refresh, after the connection has ended | `400` with `error` `invalid_grant` and no `error_reason` | Delete the tokens and ask the user to connect again |
| A code exchange, when the member stopped being verified after the code was issued | `400` with `error` `invalid_grant` and `error_reason` `account_pending` | No tokens were issued, and the code is not used up: the same code can be exchanged once they are verified, if that happens before it expires. Otherwise start a new connect |
| A code exchange or refresh, when STX could not check the member's account in time | `503` with `error` `temporarily_unavailable` and a `Retry-After` header | Retry with the same code or token |

An API call with the member's access token, while they have not finished verification, answers `401`:

```json
{"error": "Missing or invalid OAuth access token"}
```

The refresh you then try answers `400`, and `error_reason` tells you why:

```json
{"error": "invalid_grant", "error_reason": "account_pending", "error_description": "the member's account is awaiting verification"}
```

Once the member is verified, the same refresh token works again and returns a new pair:

```json
{
  "access_token": "stxapp_at_TX…",
  "refresh_token": "stxapp_rt_2v…",
  "token_type": "bearer",
  "expires_in": 3600,
  "scope": "profile.read"
}
```

When STX could not check the member's account in time, the answer is `503` with `Retry-After: 1`. Nothing was decided, so send the same request again:

```json
{"error": "temporarily_unavailable", "error_description": "the grant could not be processed; retry"}
```

Read `error_reason` before you act on `invalid_grant`. With `error_reason` set to `account_pending`, keep the tokens. On a refresh with no `error_reason`, the connection is over, even if the member also happens not to be verified: delete the tokens. On a code exchange with no `error_reason`, that code cannot be used: start a new connect.

## Open WebSocket connections

A WebSocket opened with a member's access token is closed by STX as soon as the member stops being verified. Nothing is revoked.

| What your client sees | What it means | What to do |
| --- | --- | --- |
| The open socket closes with code `1011` and no reason. No message is sent first | STX closed it | Reconnect, with a backoff |
| The reconnect is refused with HTTP `403` | The token cannot open a socket right now | Refresh the token. The answer tells you which case this is: `error_reason` `account_pending` means the member has not finished verification, so keep the tokens and try again later; no `error_reason` means the connection is over |
| The reconnect opens | The member is verified again | Carry on with the same tokens |

## With the TypeScript SDK

The callback errors arrive as `STXAccountPendingException` and `STXAccessDeniedException`; see [With the TypeScript SDK](/apps/typescript-sdk/#connect-your-stx-account).
