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

# Node SDK quickstart

> Add Era context to one Node SDK model call.

This guide adds Era to a trusted Node.js backend. Your browser or mobile app
should never receive the Node SDK API key.

You need Node.js 18 or later, an Era API key, a partner ID, and a `visitorId`
from the [Web SDK](/web-sdk/quickstart) or [Flutter SDK](/flutter-sdk/quickstart).

<Steps>
  <Step title="Install">
    ```bash theme={null}
    npm install @seasonlabs/era-node
    ```
  </Step>

  <Step title="Create the client">
    ```typescript theme={null}
    import { Era } from "@seasonlabs/era-node";

    const era = new Era({
      apiKey: process.env.ERA_API_KEY!,
      baseUrl: process.env.ERA_URL!,
      partnerId: process.env.ERA_PARTNER_ID!,
    });
    ```

    Create one client and reuse it. Keep all three values on your backend.
  </Step>

  <Step title="Get context before the model call">
    Call `turnContext()` after adding the latest user message to `messages`.

    ```typescript theme={null}
    const eraContext = await era.turnContext(messages, {
      visitorId,
      sessionId,
    });
    ```

    Use the same `visitorId` for the same visitor. Use the same `sessionId` for
    every turn in one conversation.
  </Step>

  <Step title="Add the context to your system prompt">
    ```typescript theme={null}
    const systemPrompt = `You are a helpful assistant.

    ${eraContext}`;
    ```

    `eraContext` is a plain string. If it is empty, continue with the model call
    as usual.
  </Step>
</Steps>

## Complete example

```typescript theme={null}
import { Era } from "@seasonlabs/era-node";

const era = new Era({
  apiKey: process.env.ERA_API_KEY!,
  baseUrl: process.env.ERA_URL!,
  partnerId: process.env.ERA_PARTNER_ID!,
});

// Run this after the latest user message is in `messages`.
const eraContext = await era.turnContext(messages, {
  visitorId: "era_vid_00000000-0000-4000-8000-000000000000",
  sessionId: "conversation_123",
});

const result = await yourModel.generate({
  system: `You are a helpful assistant.\n\n${eraContext}`,
  messages,
});
```

## What to expect

The default mode is `async`:

* The first turn normally returns `""`.
* Later turns return the previous turn's prepared context.
* Network and API failures return `""` instead of breaking your chat.

Use `mode: "sync"` if you need context for the current turn and can accept the
extra latency.

## Add signed-in identity

If your backend knows the signed-in user, include your stable user ID:

```typescript theme={null}
const eraContext = await era.turnContext(messages, {
  visitorId,
  partnerEndUserId: authenticatedUser.id,
  sessionId,
});
```

You can also send a verified `email` or `phone` with `partnerEndUserId`. Never
copy those values directly from untrusted client input.

## Next steps

<CardGroup cols={2}>
  <Card title="Async and sync modes" icon="arrows-left-right" href="/concepts/async-sync">
    Choose when Era prepares context.
  </Card>

  <Card title="Node SDK reference" icon="code" href="/sdk/era-class">
    See every client method and option.
  </Card>
</CardGroup>
