# Session Token Creation

This guide explains how to create a **session token** for use with the NPS JavaScript SDK. Session tokens authorize tokenization in the browser; they are the only credentials exposed to the frontend.

> **Key idea:** JWTs stay on the server. Session tokens are the only credentials exposed to the browser.


## Prerequisites

- **JWT authentication:** Your backend must create a signed JWT before calling the session token endpoint. See [JWT Authentication](https://docs.nelnetpay.com/docs/jwt-authentication) for how to construct and sign a JWT (algorithm, claims, and examples).


## Flow

1. Your backend generates a short-lived JWT (see [JWT Authentication](https://docs.nelnetpay.com/docs/jwt-authentication)).
2. Your backend calls the session token API with that JWT.
3. NPS returns a session token.
4. Your backend sends the session token to the frontend.
5. The frontend passes the session token when initializing the Widget SDK.


## Create Session Token

**Endpoint:** `POST https://api.nelnetpay.com/auth/sessionTokens`

**Authentication:** Bearer JWT (see [JWT Authentication](https://docs.nelnetpay.com/docs/jwt-authentication)).

**Important:** The session token request must be made from **your backend** (your server), never from the browser. Your backend holds the API key and creates the JWT; the frontend must never receive or send the JWT. The frontend only receives the session token that your backend returns.

**Example: backend only (e.g. Node.js server or serverless function)**

```js
// This code runs on your backend only. Do not run this in the browser.
const jwt = createJwt(); // Implement per JWT Authentication guide (uses your API key secret)

const response = await fetch('https://api.nelnetpay.com/auth/sessionTokens', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${jwt}`
  }
});

const data = await response.json();
```

**Example: curl (backend only)**

```bash
# Replace <JWT> with a JWT created per JWT Authentication guide. Run this from your server/terminal, not from the browser.
curl -X POST https://api.nelnetpay.com/auth/sessionTokens \
  -H "Authorization: Bearer <JWT>"
```

**Success response (200)**

The API returns the following in the response body (JSON):

| Field | Type | Description |
|  --- | --- | --- |
| `responseCode` | string | Status code indicating success (e.g. `"A100"`). |
| `responseMessage` | string | Status message (e.g. `"Successful"`). |
| `sessionToken` | string | Session token to send to the frontend. Treat as sensitive. |


**Example: returning the session token to the client**

Your backend returns only the session token to the frontend (e.g. via your own API or page render). The frontend then passes it to the Widget—it never calls the session token endpoint or sees the JWT.

```js
// Still on your backend: send only the session token to the client
if (response.ok && data.responseCode === 'A100' && data.sessionToken) {
  return { sessionToken: data.sessionToken };
}
// Handle non-OK, non-A100, or missing sessionToken (see Error responses)
```

**Error responses**

- **401 Unauthorized** — Invalid or expired JWT, or signature/`sub` mismatch. Create a new JWT and retry.
- **403 Forbidden** — Client isn't allowed to access the API.
- **500 Internal Server Error** — Server error; response may include `responseCode` and `responseMessage`.


Handle these in your backend and do not expose raw error details to the browser. Return a generic failure or retry instruction to the client.

## Using the Session Token in the SDK

The session token is used **only** by the client-side Widget SDK to authorize tokenization. The frontend receives the session token from **your backend** (e.g. from an API that calls the session token endpoint above) and passes it when initializing the Widget. Do not call the session token API from the browser.

```js
const wg = new Widget({
  sessionToken,
  onReady: () => console.log('Payment form ready'),
  onTokenizationComplete: handleTokenization,
  onError: handleError,
});
```

**Session token characteristics**

- Authorize tokenization in the browser.
- Short-lived and single-purpose.
- Safe to pass to the frontend only for Widget initialization.
- Cannot be used to call backend NPS APIs (use a JWT for those).


## API reference

For the full request/response contract and versioning, see the [Session Tokens API spec](https://docs.nelnetpay.com/apis/session-token-spec/session-tokens).