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

# verifyAuth() — SocketFi Backend Token Verification

> Cryptographically verify a SocketFi access token on your backend. Returns the authenticated user ID and Stellar wallet address, or a typed error code.

`verifyAuth()` is the core function of the `@socketfi/server` SDK. Call it on every incoming request that requires authentication, passing the raw token from the `Authorization` header. The function downloads and caches SocketFi's public signing keys automatically, verifies the token's cryptographic signature, validates its claims, and returns a strongly-typed result you can act on immediately — no manual JWT configuration required.

## Function signature

```typescript theme={null}
import { verifyAuth } from '@socketfi/server';

const result: VerifyAuthResult = await verifyAuth(token: string);
```

## Parameters

<ParamField path="token" type="string" required>
  The raw SocketFi access token string. Extract this from the `Authorization: Bearer <token>` header before passing it to `verifyAuth()`. Do not include the `Bearer ` prefix.
</ParamField>

## Return value

`verifyAuth()` returns `Promise<VerifyAuthResult>`. The shape of the resolved value depends on whether verification succeeded.

### On success

<ResponseField name="valid" type="true" required>
  Always `true` when verification succeeds.
</ResponseField>

<ResponseField name="user" type="object" required>
  The verified user object.

  <Expandable title="user fields">
    <ResponseField name="user.id" type="string" required>
      The unique SocketFi user identifier (e.g. `"usr_01hx..."`). Use this value as the stable foreign key when storing user data in your database.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="wallet" type="object" required>
  The user's embedded Stellar smart wallet.

  <Expandable title="wallet fields">
    <ResponseField name="wallet.address" type="string" required>
      The user's Stellar/Soroban wallet address (e.g. `"GDZX..."`). Use this when constructing on-chain operations or looking up balances.
    </ResponseField>
  </Expandable>
</ResponseField>

### On failure

<ResponseField name="valid" type="false" required>
  Always `false` when verification fails.
</ResponseField>

<ResponseField name="error" type="object" required>
  The verification error.

  <Expandable title="error fields">
    <ResponseField name="error.code" type="string" required>
      A machine-readable error code. See the [error codes table](#error-codes) below for the full list and recommended handling.
    </ResponseField>
  </Expandable>
</ResponseField>

## Extracting the token from the Authorization header

SocketFi access tokens are sent as Bearer tokens. Parse them from the `Authorization` header before calling `verifyAuth()`:

```typescript theme={null}
const authHeader = req.headers.authorization;
const token = authHeader?.replace('Bearer ', '');

if (!token) {
  return res.status(401).json({ error: 'Unauthorized' });
}
```

<Warning>
  Call `verifyAuth()` on **every** protected request. Never cache or reuse the result across requests — each call re-validates the token's expiry and signature freshness.
</Warning>

## Success example

```typescript theme={null}
import { verifyAuth } from '@socketfi/server';

const token = req.headers.authorization?.replace('Bearer ', '');
const auth = await verifyAuth(token);

if (auth.valid) {
  console.log(auth);
  // {
  //   valid: true,
  //   user: { id: 'usr_01hx...' },
  //   wallet: { address: 'GDZX...' }
  // }

  // Safe to proceed — user is authenticated
  return res.json({ user: auth.user, wallet: auth.wallet });
}
```

## Failure example

```typescript theme={null}
import { verifyAuth } from '@socketfi/server';

const token = req.headers.authorization?.replace('Bearer ', '');
const auth = await verifyAuth(token);

if (!auth.valid) {
  console.log(auth);
  // {
  //   valid: false,
  //   error: { code: 'TOKEN_EXPIRED' }
  // }

  return res.status(401).json({ error: 'Unauthorized' });
}
```

## Complete protected route example

```typescript theme={null}
import express, { Request, Response } from 'express';
import { verifyAuth } from '@socketfi/server';

const app = express();

app.get('/account', async (req: Request, res: Response) => {
  const token = req.headers.authorization?.replace('Bearer ', '');

  if (!token) {
    return res.status(401).json({ error: 'Missing token' });
  }

  const auth = await verifyAuth(token);

  if (!auth.valid) {
    return res.status(401).json({ error: auth.error.code });
  }

  // auth.user.id and auth.wallet.address are now safe to use
  const userData = await db.users.findOne({ id: auth.user.id });

  return res.json({ user: userData, wallet: auth.wallet });
});
```

## Error codes

The following error codes can appear in `auth.error.code` when `auth.valid` is `false`:

| Code                | Meaning                                                            | How to handle                                                                |
| ------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------- |
| `TOKEN_REQUIRED`    | No token was provided (empty or `undefined` string passed).        | Check that the client is sending the `Authorization: Bearer <token>` header. |
| `INVALID_SIGNATURE` | The token's cryptographic signature did not pass verification.     | Reject the request. The token may have been tampered with or forged.         |
| `TOKEN_EXPIRED`     | The token's expiry claim is in the past.                           | Return a `401` and prompt the user to re-authenticate via the client SDK.    |
| `INVALID_ISSUER`    | The token's issuer claim does not match SocketFi's expected value. | Reject the request. The token was not issued by SocketFi.                    |

<Note>
  You do not need to configure signing keys, JWKS URLs, or JWT libraries. `verifyAuth()` handles all of that automatically. If you need to force-refresh the cached public keys (for example, during key-rotation testing), call `clearKeyCache()` before the next verification.
</Note>
