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

# Installation

> Install the Synap SDK for Python, JavaScript, or TypeScript, configure environment variables, and verify your setup.

Synap ships **two runtime SDKs**: a native Python SDK, and a Node.js SDK that also serves TypeScript. Pick your language below. Each has its own complete setup path.

|                    | Python                    | JavaScript                        | TypeScript                                |
| ------------------ | ------------------------- | --------------------------------- | ----------------------------------------- |
| **Package**        | `maximem-synap` (PyPI)    | `@maximem/synap-js-sdk` (npm)     | `@maximem/synap-js-sdk` (npm)             |
| **Runtime needed** | Python 3.11+              | Node.js 18+ **and** Python 3.11+  | Node.js 18+ **and** Python 3.11+          |
| **Setup steps**    | 1 (install)               | 2 (install + runtime setup)       | 3 (install + runtime setup + TS setup)    |
| **Types**          | Built-in type hints       | —                                 | Bundled `.d.ts` + generated typed wrapper |
| **Guide**          | [Python SDK](#python-sdk) | [JavaScript SDK](#javascript-sdk) | [TypeScript SDK](#typescript-sdk)         |

<Note>
  JavaScript and TypeScript are served by the **same npm package**. TypeScript is not a separate SDK: it is the JavaScript SDK plus a bundled type definition file and one extra setup command. The two sections below are written to be followed independently, so you never need to read the other one.
</Note>

<Warning>
  **Both Node.js SDKs require Python 3.11+ on the host.** `@maximem/synap-js-sdk` is a thin wrapper that runs the Python SDK as a subprocess. `npm install` alone is **not** enough; you must also run the runtime setup step. See [where the Node.js SDK does not run](#unsupported-runtimes).
</Warning>

***

## Python SDK

### Requirements

* **Python 3.11+**: the SDK uses modern Python features including `asyncio`, type hints, and structural pattern matching
* **pip 21.0+**, **Poetry 1.2+**, or **uv 0.4+** for package management
* **An active Synap account**: [Sign up at synap.maximem.ai](https://synap.maximem.ai)

### Install

<CodeGroup>
  ```bash pip theme={null}
  pip install maximem-synap
  ```

  ```bash poetry theme={null}
  poetry add maximem-synap
  ```

  ```bash uv theme={null}
  uv add maximem-synap
  # pip-compatible (existing venv): uv pip install maximem-synap
  ```

  ```bash requirements.txt theme={null}
  # Add to your requirements.txt
  maximem-synap>=0.4.2
  ```
</CodeGroup>

<Note>
  The package name uses a hyphen (`maximem-synap`) but the import name uses an underscore (`maximem_synap`). Install with `pip install maximem-synap`, then `from maximem_synap import MaximemSynapSDK` in your code.
</Note>

<Warning>
  **Pin at least 0.4.1 if one process ever uses more than one API key**: a per-tenant backend, a worker that switches keys between jobs, or staging and production side by side. In 0.4.0 and earlier, the second and later SDKs in a process silently adopted the first one's credentials, so their reads returned the first key's memory and their writes were committed against it. See the [0.4.1 release notes](/resources/changelog). A single-API-key process is unaffected.
</Warning>

This installs the SDK with the following dependencies:

* `httpx`: async HTTP client used by the SDK
* `pydantic`: data validation and settings management
* `cryptography`: credential handling
* Additional transport dependencies pulled in automatically; no extra install needed.

### Configure

Set your API key. See [environment variables](#environment-variables) for all options.

```bash theme={null}
export SYNAP_API_KEY="synap_your_key_here"
```

### Verify

Run this script to verify your installation and connectivity:

```python verify_synap.py theme={null}
import asyncio
from maximem_synap import MaximemSynapSDK

async def verify():
    try:
        sdk = MaximemSynapSDK(
            api_key="synap_your_key_here"
        )
        await sdk.initialize()
        print("[OK] SDK initialized successfully")
        print("[OK] Connected to Synap")
        await sdk.shutdown()
        print("[OK] SDK shut down cleanly")
    except Exception as e:
        print(f"[ERROR] {e}")

if __name__ == "__main__":
    asyncio.run(verify())
```

```bash theme={null}
python verify_synap.py
```

Expected output:

```
[OK] SDK initialized successfully
[OK] Connected to instance: inst_a1b2c3d4e5f67890
[OK] SDK shut down cleanly
```

### Async-first design

<Note>
  The Python SDK is async-first. All SDK methods that interact with Synap Cloud are `async` and must be called with `await` inside an `async` function.

  If you're integrating with a synchronous codebase, use `asyncio.run()` to bridge the gap:

  ```python theme={null}
  import asyncio
  from maximem_synap import MaximemSynapSDK

  def ingest_sync(document: str, user_id: str, customer_id: str):
      """Synchronous wrapper for async ingestion."""
      async def _ingest():
          sdk = MaximemSynapSDK(
              api_key="synap_your_key_here"
          )
          await sdk.initialize()
          result = await sdk.memories.create(
              document=document,
              document_type="ai-chat-conversation",
              user_id=user_id,
              customer_id=customer_id,
          )
          await sdk.shutdown()
          return result

      return asyncio.run(_ingest())
  ```

  For frameworks that already run an event loop (FastAPI, Sanic, aiohttp), use the SDK directly without wrapping.
</Note>

***

<div id="javascript-typescript-sdk" />

## JavaScript SDK

For Node.js applications using CommonJS or plain JavaScript. If you are writing TypeScript, follow the [TypeScript SDK](#typescript-sdk) section instead; it is a superset of this one.

### Requirements

* **Node.js 18+**
* **Python 3.11+ on the host**: the SDK runs the Python SDK in a subprocess
* **An active Synap account**: [Sign up at synap.maximem.ai](https://synap.maximem.ai)

### Step 1: Install the package

```bash theme={null}
npm install @maximem/synap-js-sdk
```

### Step 2: Install the Python runtime

<Warning>
  **This step is required.** `npm install` only installs the Node.js wrapper. Without it, `init()` throws `No usable Python runtime found`.
</Warning>

```bash theme={null}
npx synap-js-sdk setup --upgrade
```

This creates a managed virtual environment at `~/.synap-js-sdk/.venv` and installs the `maximem-synap` Python package into it. Your project's own Python environment is left untouched.

If `python3` on your `PATH` is older than 3.11, point the bootstrap at a newer interpreter and recreate the environment:

```bash theme={null}
npx synap-js-sdk setup --python python3.11 --force-recreate-venv --upgrade
```

<div id="setup-options" />

<Accordion title="All `setup` options">
  | Flag                    | Description                                            |
  | ----------------------- | ------------------------------------------------------ |
  | `--python <bin>`        | Python bootstrap binary (default: `python3`)           |
  | `--sdk-home <path>`     | SDK home directory (default: `~/.synap-js-sdk`)        |
  | `--venv <path>`         | Virtual environment path (default: `<sdk-home>/.venv`) |
  | `--package <name>`      | Python package name (default: `maximem-synap`)         |
  | `--sdk-version <ver>`   | Pin a specific Python SDK version                      |
  | `--upgrade`             | Install with `pip --upgrade`                           |
  | `--force-recreate-venv` | Recreate the virtual environment from scratch          |
  | `--no-deps`             | Install without dependencies                           |
  | `--no-build-isolation`  | Disable pip build isolation                            |
</Accordion>

<Warning>
  Do not pin below `0.2.3` with `--sdk-version`. The wrapper authenticates with an API key, and earlier releases predate API-key auth, so `init()` fails with `__init__() got an unexpected keyword argument 'api_key'`. Leave the version unpinned unless you have a specific reason.
</Warning>

<Tip>
  **Automating deploys?** You can skip the separate CLI call by passing `autoSetup: true` to `createClient()`, which provisions the runtime on first `init()`. It defaults to `false` because it makes your first request install packages over the network. For containers, prefer running `npx synap-js-sdk setup --upgrade` as a build step so the image ships ready to run.
</Tip>

### Step 3: Verify the runtime

<CodeGroup>
  ```bash macOS / Linux theme={null}
  ~/.synap-js-sdk/.venv/bin/python -c "import maximem_synap; print(maximem_synap.__version__)"
  ```

  ```powershell Windows theme={null}
  & "$env:USERPROFILE\.synap-js-sdk\.venv\Scripts\python.exe" -c "import maximem_synap; print(maximem_synap.__version__)"
  ```
</CodeGroup>

This prints the installed Python SDK version. If it errors, re-run Step 2.

### Step 4: Configure

Set your API key. See [environment variables](#environment-variables) for all options.

```bash theme={null}
export SYNAP_API_KEY="synap_your_key_here"
```

### Module format

<Warning>
  The package is published as **CommonJS**. In a native ES module context (a `package.json` with `"type": "module"`, or an `.mjs` file), **named imports fail at runtime**:

  ```js theme={null}
  // ❌ SyntaxError: Named export 'createClient' not found.
  import { createClient } from "@maximem/synap-js-sdk";
  ```

  Use `require()` in CommonJS, or a default import in ES modules:

  ```js theme={null}
  // ✅ CommonJS
  const { createClient } = require("@maximem/synap-js-sdk");

  // ✅ ES modules
  import pkg from "@maximem/synap-js-sdk";
  const { createClient } = pkg;
  ```
</Warning>

### Quick start

```js theme={null}
const { createClient } = require('@maximem/synap-js-sdk');

const synap = createClient({
  apiKey: process.env.SYNAP_API_KEY,
});

async function run() {
  await synap.init();

  await synap.addMemory({
    userId: 'user-123',
    customerId: 'customer-456',
    conversationId: 'conv-123',
    messages: [{ role: 'user', content: 'My name is Alex and I live in Austin.' }],
  });

  const context = await synap.fetchUserContext({
    userId: 'user-123',
    customerId: 'customer-456',
    conversationId: 'conv-123',
    searchQuery: ['Where does the user live?'],
    maxResults: 10,
  });

  console.log(context.facts);

  await synap.shutdown();
}

run().catch(console.error);
```

<Note>
  The Node.js SDK is promise-based: every method returns a `Promise`. Call `init()` once before your first operation and `shutdown()` when your process exits. Note the method is `init()` here, whereas the Python SDK uses `initialize()`.
</Note>

### API surface: flat and namespaced

The client exposes two interchangeable call styles against the same client instance.

**Flat methods** are the original JavaScript-idiomatic surface, returning camelCase results:

```js theme={null}
await synap.addMemory({ userId, customerId, messages });
await synap.searchMemory({ userId, customerId, query: 'seat preference' });
await synap.getMemories({ userId, customerId });
await synap.fetchUserContext({ userId, customerId, searchQuery: ['seat preference'] });
await synap.fetchCustomerContext({ customerId });
await synap.fetchClientContext();
await synap.getContextForPrompt({ conversationId, style: 'structured' });
await synap.deleteMemory({ userId, customerId, memoryId });
```

**Namespaced methods** were added in `@maximem/synap-js-sdk` 0.3.0, mirroring the Python SDK one-to-one so the same call shapes work in both languages:

```js theme={null}
await synap.conversation.record_message({
  conversationId,           // a UUID
  role: 'user',
  content: 'I prefer window seats',
  userId,
  customerId,               // required; on B2C pass the same value as userId
});

await synap.memories.create({
  document: 'Acme upgraded to the Pro plan',
  userId,
  customerId,
});

await synap.user.context.fetch({ userId, customerId, searchQuery: ['seat preference'] });
await synap.conversation.context.get_context_for_prompt({ conversationId });
```

The full namespaced surface is `sdk.fetch()`, `sdk.conversation.record_message()`, `sdk.conversation.context.get_context_for_prompt()`, `sdk.conversation.context.fetch()`, `sdk.memories.create()`, and `sdk.{user,customer,client}.context.fetch()`. Argument keys may be `camelCase` or `snake_case`.

<Note>
  Both surfaces are fully supported; the namespaced methods were added **alongside** the flat ones, not as a replacement. The difference is the response shape: namespaced methods return the raw snake\_case response that the framework integrations (`@maximem/synap-mastra`, `@maximem/synap-claude-agent`) consume, so a `createClient()` instance can be passed straight into them. Flat methods return normalized camelCase objects.
</Note>

### Client options

Pass these to `createClient({ ... })`:

<ResponseField name="apiKey" type="string">
  Your Synap API key. Falls back to `SYNAP_API_KEY` when omitted.
</ResponseField>

<ResponseField name="autoSetup" type="boolean" default="false">
  Provision the Python runtime automatically on first `init()` instead of requiring `npx synap-js-sdk setup`.
</ResponseField>

<ResponseField name="pythonBin" type="string">
  Path to a specific Python interpreter, bypassing runtime discovery. Falls back to `SYNAP_PYTHON_BIN`.
</ResponseField>

<ResponseField name="sdkHome" type="string">
  Managed runtime directory (default: `~/.synap-js-sdk`). Falls back to `SYNAP_JS_SDK_HOME`.
</ResponseField>

<ResponseField name="requestTimeoutMs" type="number">
  Per-request timeout. `initTimeoutMs` and `ingestTimeoutMs` override it for initialization and ingestion respectively.
</ResponseField>

<ResponseField name="onLog" type="function">
  Callback receiving `(level, message)` for wrapper diagnostics, where `level` is `'debug'` or `'error'`.
</ResponseField>

<div id="unsupported-runtimes" />

### Where the Node.js SDK does not run

Because the wrapper spawns a Python subprocess, it cannot run on platforms without a Python 3.11+ interpreter:

* **Not supported**: Vercel Edge Runtime, Cloudflare Workers, Deno Deploy, and AWS Lambda Node-only runtimes.
* **Supported**: long-running Node.js servers, container deployments, and AWS Lambda with a custom layer that includes Python.

If you are on a Python-less runtime, deploy a separate backend service with Python 3.11+ and call it from your Edge handlers, or use [`@maximem/synap-vercel-adk`](#vercel-ai-sdk-middleware) on the Node.js half of a Next.js app.

***

## TypeScript SDK

TypeScript is served by the same `@maximem/synap-js-sdk` package. Type definitions ship with the package, so `import` statements are typed the moment you install it, and a `setup-ts` command scaffolds the compiler configuration for you.

### Requirements

* **Node.js 18+**
* **Python 3.11+ on the host**: the SDK runs the Python SDK in a subprocess
* **TypeScript 5+** (installed for you in Step 3)
* **An active Synap account**: [Sign up at synap.maximem.ai](https://synap.maximem.ai)

### Step 1: Install the package

```bash theme={null}
npm install @maximem/synap-js-sdk
```

### Step 2: Install the Python runtime

<Warning>
  **This step is required.** Without it, `init()` throws `No usable Python runtime found`.
</Warning>

```bash theme={null}
npx synap-js-sdk setup --upgrade
```

This creates a managed virtual environment at `~/.synap-js-sdk/.venv` and installs the `maximem-synap` Python package into it. See [all `setup` options](#setup-options) for flags such as `--python python3.11` and `--force-recreate-venv`.

### Step 3: Set up TypeScript

```bash theme={null}
npx synap-js-sdk setup-ts
```

This command:

1. Installs `typescript` and `@types/node` as dev dependencies, auto-detecting whether your project uses **npm**, **pnpm**, **yarn**, or **bun** from its lockfile.
2. Generates a `tsconfig.json` configured correctly for the SDK, **if one does not already exist**.
3. Generates a typed wrapper at `src/synap.ts`, **if one does not already exist**.

<Note>
  Existing files are never overwritten. If you already have a `tsconfig.json`, it is left alone. Check it against [tsconfig requirements](#tsconfig-requirements) below. Pass `--force` to overwrite deliberately.
</Note>

<Accordion title="All `setup-ts` options">
  | Flag                       | Description                                                                  |
  | -------------------------- | ---------------------------------------------------------------------------- |
  | `--project-dir <path>`     | Target Node project directory (default: current directory)                   |
  | `--package-manager <name>` | `npm`, `pnpm`, `yarn`, or `bun` (auto-detected from the lockfile if omitted) |
  | `--skip-install`           | Skip installing `typescript` and `@types/node`                               |
  | `--tsconfig-path <path>`   | Where to write `tsconfig.json` (default: `tsconfig.json`)                    |
  | `--wrapper-path <path>`    | Where to write the typed wrapper (default: `src/synap.ts`)                   |
  | `--no-wrapper`             | Do not generate the typed wrapper file                                       |
  | `--force`                  | Overwrite generated files when they already exist                            |
</Accordion>

<Tip>
  **One-line setup** for a fresh TypeScript project:

  ```bash theme={null}
  npm install @maximem/synap-js-sdk && npx synap-js-sdk setup --upgrade && npx synap-js-sdk setup-ts
  ```
</Tip>

### Step 4: Configure

Set your API key. See [environment variables](#environment-variables) for all options.

```bash theme={null}
export SYNAP_API_KEY="synap_your_key_here"
```

<div id="tsconfig-requirements" />

### tsconfig requirements

The generated `tsconfig.json` is:

```json tsconfig.json theme={null}
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "CommonJS",
    "moduleResolution": "Node",
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true,
    "outDir": "dist"
  },
  "include": ["src/**/*.ts", "types/**/*.d.ts"]
}
```

<Warning>
  **`"module": "CommonJS"` matters.** The package is published as CommonJS. When TypeScript compiles to CommonJS, a named import works and is fully typed:

  ```ts theme={null}
  // ✅ compiles to require() and works
  import { createClient } from "@maximem/synap-js-sdk";
  ```

  If your project emits **native ES modules** instead (`"module": "NodeNext"` / `"ESNext"`, or a `package.json` with `"type": "module"`), that same line throws `SyntaxError: Named export 'createClient' not found` at runtime. Use a default import there:

  ```ts theme={null}
  // ✅ ES module output
  import pkg from "@maximem/synap-js-sdk";
  const { createClient } = pkg;
  ```

  `esModuleInterop: true` is required either way.
</Warning>

### Quick start

```ts src/index.ts theme={null}
import { createClient, type SynapClient } from "@maximem/synap-js-sdk";

const synap: SynapClient = createClient({
  apiKey: process.env.SYNAP_API_KEY,
});

async function run(): Promise<void> {
  await synap.init();

  await synap.addMemory({
    userId: "user-123",
    customerId: "customer-456",
    conversationId: "conv-123",
    messages: [{ role: "user", content: "My name is Alex and I live in Austin." }],
  });

  const context = await synap.fetchUserContext({
    userId: "user-123",
    customerId: "customer-456",
    searchQuery: ["Where does the user live?"],
    maxResults: 10,
  });

  context.facts.forEach((fact) => {
    console.log(fact.content, fact.confidence);
  });

  await synap.shutdown();
}

run().catch(console.error);
```

### The generated typed wrapper

`setup-ts` writes a `SynapTsClient` class to `src/synap.ts` that wraps the client with explicit parameter types on every method. Use it if you prefer injecting a narrow, typed dependency into your services rather than passing the raw client around:

```ts theme={null}
import { createTsClient } from "./synap";

const synap = createTsClient({ apiKey: process.env.SYNAP_API_KEY });

async function main() {
  await synap.init();
  // ... use synap
  await synap.shutdown();
}
```

It exposes `init()`, `addMemory()`, `searchMemory()`, `getMemories()`, `fetchUserContext()`, `fetchCustomerContext()`, `fetchClientContext()`, `getContextForPrompt()`, `deleteMemory()`, and `shutdown()`. The file is yours once generated: edit it freely. Skip it entirely with `--no-wrapper` and use `createClient()` directly.

### Exported types

All types are exported from the package root. The most commonly used:

| Category           | Types                                                                                                                                                                                       |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Client**         | `SynapClient`, `SynapClientOptions`                                                                                                                                                         |
| **Inputs**         | `AddMemoryInput`, `SearchMemoryInput`, `GetMemoriesInput`, `DeleteMemoryInput`, `FetchUserContextInput`, `FetchCustomerContextInput`, `FetchClientContextInput`, `GetContextForPromptInput` |
| **Results**        | `AddMemoryResult`, `SearchMemoryResult`, `GetMemoriesResult`, `DeleteMemoryResult`, `ContextResponse`, `ContextForPromptResult`                                                             |
| **Memory objects** | `Fact`, `Preference`, `Episode`, `Emotion`, `TemporalEvent`, `MemoryItem`, `ConversationContext`                                                                                            |
| **Unions**         | `RetrievalMode` (`'fast' \| 'accurate'`), `IngestMode` (`'fast' \| 'long-range'`), `ContextType`, `DocumentType`, `PromptStyle`                                                             |

```ts theme={null}
import type {
  SynapClientOptions,
  ContextResponse,
  Fact,
  RetrievalMode,
} from "@maximem/synap-js-sdk";

function summarize(context: ContextResponse): string {
  return context.facts.map((f: Fact) => f.content).join("; ");
}
```

<Note>
  Temporal fields are exposed in TypeScript as `eventDate`, `validUntil`, `temporalCategory`, and `temporalConfidence` on memory objects, plus a top-level `temporalEvents` array on `ContextResponse`.
</Note>

### Typed error handling

Error classes are exported as real classes, so `instanceof` narrowing works:

```ts theme={null}
import {
  RateLimitError,
  AuthenticationError,
  InsufficientCreditsError,
} from "@maximem/synap-js-sdk";

try {
  await synap.fetchUserContext({ userId, customerId });
} catch (error) {
  if (error instanceof RateLimitError) {
    console.warn(`Retry after ${error.retryAfterSeconds}s`);
  } else if (error instanceof AuthenticationError) {
    console.error("Check SYNAP_API_KEY");
  } else if (error instanceof InsufficientCreditsError) {
    console.error(`Top up: ${error.recoveryUrl}`);
  }
}
```

<Note>
  Every error derives from `SynapError`, split into `SynapTransientError` (safe to retry) and `SynapPermanentError` (do not retry). See [Error handling](/sdk/error-handling).
</Note>

<Warning>
  The named import above works because the generated `tsconfig.json` compiles to CommonJS. In a **native ES module** project it throws `SyntaxError: Named export 'RateLimitError' not found`, so reach the error classes through a default import instead:

  ```ts theme={null}
  import pkg from "@maximem/synap-js-sdk";
  const { RateLimitError } = pkg;
  ```

  Types are unaffected either way: `import type { ... }` is erased at compile time and always works. See [module format](#module-format).
</Warning>

***

### Vercel AI SDK Middleware

If your application uses the [Vercel AI SDK](https://sdk.vercel.ai), use the `@maximem/synap-vercel-adk` middleware package. It wraps any `LanguageModelV1`-compatible model and injects Synap context automatically, with no changes to your existing `generateText` / `streamText` calls.

```bash theme={null}
npm install @maximem/synap-vercel-adk
```

Requires Node.js 18+, Python 3.11+ on the host (the middleware inherits the Node.js SDK's runtime requirement above), and `ai >=3.0.0` as a peer dependency. TypeScript types are included.

<Warning>
  `@maximem/synap-vercel-adk` inherits the Python-subprocess requirement and **does not run on Next.js Edge Runtime**. Pin route handlers to `export const runtime = "nodejs"`. If your Vercel deployment must run on Edge, place a separate Python-capable backend between the Edge handler and Synap.
</Warning>

***

## Environment variables

The SDK reads configuration from environment variables. This is the recommended approach for production deployments.

### All languages

<ResponseField name="SYNAP_API_KEY" type="string" required>
  Your API key for SDK authentication. Generated in the Dashboard: navigate to your instance and click **Generate API Key**. Starts with `synap_`.
</ResponseField>

<ResponseField name="SYNAP_INSTANCE_ID" type="string">
  Records which instance you are on. Optional; the dashboard gives you it alongside the API key so you can paste both in one go. Starts with `inst_`.
</ResponseField>

<ResponseField name="SYNAP_LOG_LEVEL" type="string">
  Logging verbosity for the SDK. Accepts standard logging levels: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`. Defaults to `INFO`.
</ResponseField>

<Warning>
  Set the instance id as an **environment variable**, not as a constructor argument. `SYNAP_INSTANCE_ID` records which instance you are on and leaves the SDK keyed on your credential. Passing `instance_id=` to `MaximemSynapSDK(...)` is different: it makes the id the identity, so a second key used under it is silently discarded and key rotation stops taking effect. See [Singleton Pattern](/sdk/initialization#singleton-pattern).
</Warning>

### JavaScript and TypeScript only

These control how the wrapper locates its Python runtime. You only need them for non-default setups.

<ResponseField name="SYNAP_PYTHON_BIN" type="string">
  Path to a specific Python interpreter, bypassing runtime discovery.
</ResponseField>

<ResponseField name="SYNAP_JS_SDK_HOME" type="string">
  Managed runtime directory used by `synap-js-sdk setup`. Defaults to `~/.synap-js-sdk`.
</ResponseField>

<ResponseField name="SYNAP_PYTHON_BOOTSTRAP" type="string">
  Interpreter used to create the virtual environment during setup. Defaults to `python3`.
</ResponseField>

<ResponseField name="SYNAP_PY_SDK_VERSION" type="string">
  Pin the Python SDK version installed by `synap-js-sdk setup`. Leave unset to install the latest.
</ResponseField>

### Setting them

<CodeGroup>
  ```bash Linux / macOS theme={null}
  export SYNAP_API_KEY="synap_your_key_here"
  export SYNAP_INSTANCE_ID="inst_your_instance_id"
  export SYNAP_LOG_LEVEL="INFO"
  ```

  ```powershell Windows (PowerShell) theme={null}
  $env:SYNAP_API_KEY = "synap_your_key_here"
  $env:SYNAP_INSTANCE_ID = "inst_your_instance_id"
  $env:SYNAP_LOG_LEVEL = "INFO"
  ```

  ```ini .env file theme={null}
  SYNAP_API_KEY=synap_your_key_here
  SYNAP_INSTANCE_ID=inst_your_instance_id
  SYNAP_LOG_LEVEL=INFO
  ```
</CodeGroup>

<Warning>
  Never commit API keys to version control. Use a secrets manager (AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault) or environment variables in production.
</Warning>

## Credential storage

The SDK reads the API key from `SYNAP_API_KEY` (or the `api_key` / `apiKey` constructor argument) on every startup. There is no on-disk credential cache; the key lives wherever your secrets manager or environment configuration puts it.

<CodeGroup>
  ```python Python theme={null}
  # Reads SYNAP_API_KEY from the environment
  sdk = MaximemSynapSDK()

  # Or pass the key explicitly
  sdk = MaximemSynapSDK(
      api_key="synap_your_key_here"
  )
  ```

  ```js JavaScript / TypeScript theme={null}
  // Reads SYNAP_API_KEY from the environment
  const synap = createClient();

  // Or pass the key explicitly
  const synap = createClient({
    apiKey: "synap_your_key_here",
  });
  ```
</CodeGroup>

<Tip>
  In Kubernetes, mount the API key as a secret and reference it via `SYNAP_API_KEY` in your pod spec. The same pattern works for Docker, Vercel, and AWS Lambda (Python 3.11+ on host required).
</Tip>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Python: ImportError: No module named 'maximem_synap'">
    Verify the package is installed in your active Python environment:

    ```bash theme={null}
    pip show maximem-synap
    ```

    If using a virtual environment, make sure it's activated. If using Poetry, prefix commands with `poetry run`.
  </Accordion>

  <Accordion title="JS/TS: No usable Python runtime found">
    You installed the npm package but skipped the runtime setup step. Run:

    ```bash theme={null}
    npx synap-js-sdk setup --upgrade
    ```

    If your default `python3` is older than 3.11, point the bootstrap at a newer interpreter:

    ```bash theme={null}
    npx synap-js-sdk setup --python python3.11 --force-recreate-venv --upgrade
    ```

    Alternatively, pass `pythonBin` in `createClient()` options to use an interpreter you manage yourself.
  </Accordion>

  <Accordion title="JS/TS: Python SDK import failed">
    The interpreter was found but `maximem_synap` is not installed in it. This usually means the managed environment was created but the install did not complete. Re-run setup with `--upgrade`, then confirm:

    ```bash theme={null}
    ~/.synap-js-sdk/.venv/bin/python -c "import maximem_synap; print(maximem_synap.__version__)"
    ```
  </Accordion>

  <Accordion title="JS/TS: SyntaxError: Named export 'createClient' not found">
    Your project is running as native ES modules, but the package is CommonJS. Switch to a default import:

    ```js theme={null}
    import pkg from "@maximem/synap-js-sdk";
    const { createClient } = pkg;
    ```

    Or compile with `"module": "CommonJS"`. See [module format](#module-format).
  </Accordion>

  <Accordion title="TypeScript: Cannot find module '@maximem/synap-js-sdk' or its type declarations">
    Set `"moduleResolution": "Node"` (or `"Bundler"`) and `"esModuleInterop": true` in your `tsconfig.json`. Running `npx synap-js-sdk setup-ts` generates a configuration with the correct values. If you already have a `tsconfig.json`, it is not overwritten. Compare it against [tsconfig requirements](#tsconfig-requirements).
  </Accordion>

  <Accordion title="Connection refused or timeout during initialization">
    Check that:

    1. Your outbound network connectivity to Synap Cloud is permitted.
    2. If behind a corporate proxy, configure `HTTPS_PROXY` in your environment.
    3. Your `SYNAP_API_KEY` is correct and the key is active in the dashboard.
  </Accordion>

  <Accordion title="API key rejected">
    If the SDK reports an authentication failure:

    1. Confirm `SYNAP_API_KEY` starts with `synap_` and is not wrapped in quotes in your shell
    2. Check the key is still active in the Dashboard (Instance → API Keys)
    3. If the key was revoked, generate a new one and update your `.env` or secrets manager
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={3}>
  <Card title="Authentication" icon="lock" href="/setup/authentication">
    Configure API key authentication, multiple keys per instance, and key rotation.
  </Card>

  <Card title="Integration" icon="plug" href="/setup/detailed-integration">
    Connect Synap to your application framework and infrastructure.
  </Card>

  <Card title="SDK Initialization" icon="code" href="/sdk/initialization">
    Explore all SDK initialization options, including custom credential providers.
  </Card>
</CardGroup>
