> ## 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.

# Changelog

> All notable changes to the Synap SDK and API are documented here. This project follows [Semantic Versioning](https://semver.org/) (SemVer).

* **Major** versions introduce breaking changes to the API or SDK interfaces
* **Minor** versions add new features in a backward-compatible manner
* **Patch** versions contain backward-compatible bug fixes

<Tip>
  Subscribe to release notifications by watching the [maximem\_synap\_sdk](https://github.com/maximem-ai/maximem_synap_sdk) repository on GitHub, or join the `#releases` channel on [Discord](https://discord.gg/synap) for real-time updates.
</Tip>

## Compatibility Matrix

Use this table to pick compatible versions when pinning dependencies.

### Core SDK

| `maximem-synap` | Python | `httpx`         | `pydantic`  | `grpcio` | Cloud API |
| --------------- | ------ | --------------- | ----------- | -------- | --------- |
| 0.4.x           | ≥ 3.11 | ≥ 0.27, \< 0.29 | ≥ 2.5, \< 3 | ≥ 1.60   | v1        |
| 0.2.x           | ≥ 3.11 | ≥ 0.27, \< 0.29 | ≥ 2.5, \< 3 | ≥ 1.60   | v1        |
| 0.1.x           | ≥ 3.11 | ≥ 0.27, \< 0.29 | ≥ 2.5, \< 3 | ≥ 1.60   | v1        |

### Integration packages

| Package                            | Pins core SDK    | Pins framework                            | Notes                              |
| ---------------------------------- | ---------------- | ----------------------------------------- | ---------------------------------- |
| `maximem-synap-langchain`          | ≥ 0.1            | `langchain` ≥ 0.2, `langchain-core` ≥ 0.2 |                                    |
| `maximem-synap-langgraph`          | ≥ 0.1            | `langgraph` ≥ 0.2                         |                                    |
| `maximem-synap-llamaindex`         | ≥ 0.1            | `llama-index-core` ≥ 0.11                 |                                    |
| `maximem-synap-openai-agents`      | ≥ 0.1            | `openai` ≥ 1.30                           |                                    |
| `maximem-synap-pydantic-ai`        | ≥ 0.1            | `pydantic-ai` ≥ 0.0.13                    |                                    |
| `maximem-synap-crewai`             | ≥ 0.1            | `crewai` ≥ 0.60                           |                                    |
| `maximem-synap-autogen`            | ≥ 0.1            | `autogen-agentchat` ≥ 0.4                 |                                    |
| `maximem-synap-google-adk`         | ≥ 0.1            | `google-adk` ≥ 0.1                        |                                    |
| `maximem-synap-haystack`           | ≥ 0.1            | `haystack-ai` ≥ 2.5                       |                                    |
| `maximem-synap-agno`               | ≥ 0.1            | `agno` ≥ 1.0                              |                                    |
| `maximem-synap-semantic-kernel`    | ≥ 0.1            | `semantic-kernel` ≥ 1.0                   |                                    |
| `maximem-synap-microsoft-agent`    | ≥ 0.1            | `agent-framework` ≥ 0.1                   |                                    |
| `maximem-synap-nemo-agent-toolkit` | ≥ 0.1            | `nemo-agent-toolkit` ≥ 0.5                |                                    |
| `maximem-synap-livekit-agents`     | ≥ 0.1            | `livekit-agents` ≥ 0.10                   |                                    |
| `maximem-synap-pipecat`            | ≥ 0.1            | `pipecat-ai` ≥ 0.0.50                     |                                    |
| `maximem-synap-vercel-adk`         | n/a (TS package) | `ai` ≥ 3.0                                | Node.js 18+                        |
| `maximem-synap-mastra`             | n/a (TS package) | `@mastra/core` ≥ 0.5                      | Node.js 18+                        |
| `maximem-synap-claude-agent`       | ≥ 0.1            | `claude-agent-sdk` ≥ 0.1                  | Available in Python and TypeScript |

<Note>
  Pin numbers above reflect the minimum tested. Newer minor/patch versions of the framework will typically work, but if a framework ships a breaking change, the integration package will pin around it explicitly. Check the integration package's own changelog for the exact pin if you suspect a compatibility issue.
</Note>

### Cloud API

The Cloud API is versioned at the URL prefix (`/v1/...`). The current SDK targets v1 exclusively. v2 is not on the near-term roadmap.

***

## v0.4.3, 2026-08-05

### Fixed

* **The local cache is now scoped to the instance, not just the account.** It lived at `~/.synap/{client_id}/` and addressed its files by scope and entity id alone. `client_id` identifies the Synap *account*, which can own several instances, and those are separate memory stores sharing no data (so two instances under one account wrote to the same `users/{user_id}.db`, and where the same `customer_id` or `user_id` appeared under both, one instance could be served the other's cached context. The path is now `~/.synap/{client_id}/{instance_id}/` and the instance is part of the cache key. **Server-side scoping was never affected) this was local disk only**, and it needed two instances of one account live in the same process, which only became a supported shape in 0.4.1.

<Note>
  **Your cache starts cold after this upgrade** and refills on demand; entries under the old path are not migrated. That is deliberate: a pre-0.4.3 directory may hold entries from more than one instance, and there is no way to tell which belongs to which, so moving them would carry the contamination forward. Nothing is deleted; you can remove the old `~/.synap/{client_id}/*.db`, `customers/` and `users/` entries once you have upgraded. No server-side data is involved.
</Note>

***

## v0.4.2, 2026-08-05

### Fixed

* **One Synap instance no longer ends up with two live SDKs.** An SDK built from an API key alone is identified by that key, because its `instance_id` does not exist yet; it is resolved from the key during `initialize()`. The resolved id was never recorded, so a later `MaximemSynapSDK(instance_id="inst_…")` for that same instance missed the lookup and built a second SDK: two anticipation caches, two short-term stores, two `Listen` streams and a lower local cache hit rate for one instance. `initialize()` now records the resolved id as an additional identity for the SDK. Constructing by API key keeps working exactly as before, and an `instance_id` already held by another live SDK is never taken from it.
* **Concurrent first constructions no longer diverge.** Several threads racing to build the *first* SDK for one identity could all miss the registry and the last one to finish would win, leaving every other caller holding an SDK the registry did not know about, with its own connections and caches. Construction now claims its slot atomically; the callers that lose the race receive the winner. This was reachable on a normal cold start in a multi-threaded server.
* **`shutdown()` releases every identity the SDK holds**, so nothing hands out an SDK whose transports are already closed.
* **Test modules are no longer published inside the package.** `maximem_synap-0.4.1` shipped six `test_*.py` modules into `site-packages`, one importing an internal server module that does not exist outside our monorepo, which could fail any test run that collected them. The 0.4.2 wheel and sdist contain none.
* **`maximem-synap-nemo-agent-toolkit`**: SDK teardown never ran. Both entry points probed for a `close()` method the SDK does not have (it is `shutdown()`), so the guard silently did nothing and every workflow leaked its HTTP transport, gRPC stream and telemetry collector.

<Note>
  No API was added, removed or renamed, and there is no data migration. Callers passing an explicit `instance_id` see byte-identical behaviour.
</Note>

***

## v0.4.1, 2026-08-04

### Fixed

* **Cross-tenant credential and state sharing when one process used more than one API key.** The SDK keeps one instance per Synap instance, keyed on `instance_id`, but `instance_id` is optional and empty at construction time, because it is resolved from the API key later, during `initialize()`. Every `MaximemSynapSDK(api_key=...)` therefore landed in the same registry slot, and the second one adopted the first's entire state, credentials included. In a process serving two tenants, tenant B's SDK authenticated as tenant A: B's reads returned A's memory and B's writes were committed into A's instance. It was silent (no exception, no warning, no log line) because the server correctly authenticated the key it received; it simply received the wrong one. The registry now derives its key from the credential when no `instance_id` is given (stored as a truncated SHA-256 digest, never in plaintext).
* **`shutdown()` left a stale registry entry.** Registration used the constructor's `instance_id` and unregistration used `self.instance_id`, which `initialize()` may have replaced in between. The entry survived teardown, so the registry kept handing out an SDK whose transports, stream and cache were already closed.
* **A `_force_new` SDK's `shutdown()` evicted the real singleton.** Unregistration had no ownership check, so a throwaway SDK (a test fixture, an adapter, the JS bridge) removed whatever sat on its key, taking the application's live SDK out of the registry mid-conversation.

<Warning>
  **Affects `maximem-synap` ≤ 0.4.0, and only a process that constructs the SDK with two or more different API keys**: a backend holding a key per customer, a process talking to two Synap environments at once, or a worker that switches keys between tasks. A process that uses a single API key is unaffected, which is the common case. Upgrade with `pip install --upgrade "maximem-synap>=0.4.1"`; no code changes and no data migration are required. If you did run more than one key on 0.4.0 or earlier, memory written in that period may have been stored against the first key's instance; [contact support](/resources/support) and we will help you check what was written where.
</Warning>

### Changed

* The registry now derives its key from the API key, so **each distinct key gets its own SDK**, including two keys issued against the same instance, which each authenticate as themselves. Only an explicitly passed `instance_id` still collapses several keys onto one SDK, unchanged from before. If you rotate a key inside a long-running process and construct by `instance_id`, call `await sdk.shutdown()` before reconstructing, or restart the worker. See [Rotating a key in a long-running process](/sdk/initialization#rotating-a-key-in-a-long-running-process).

***

## v0.4.0, 2026-07-17

### Added

* **`conversation.ingest_transcript(...)`**: one-shot async push of a full conversation transcript (string or typed `TranscriptTurn` list) plus optional client analysis JSON and metadata. Returns immediately with a `TranscriptIngestResponse` (`ingestion_id`, `status`, `summary_status`, …); poll with `memories.status()` / `wait_for_completion()`. Idempotent on `(conversation_id, transcript)`: an identical re-push returns `status="duplicate"` with the original `ingestion_id`; a *different* transcript under the same `conversation_id` raises `TranscriptConflictError`. Unlike `record_message`, `conversation_id` is an arbitrary client string (no UUID validation); the server coerces it and echoes the original as `external_conversation_id`.
* **Conversation-summary fetch**: `fetch(...)`, `user.context.fetch(...)` and the unified `sdk.fetch(...)` gain `context_mode` (`"in-conversation"` default / `"conversation-summary"`), `include_profile` (default `True`) and `last_n_conversations` (default `1`, range 0–20). In summary mode the response carries a caller `profile` and previous-conversation summaries instead of item lists: the call-start read for async integrations. In the unified `sdk.fetch`, these three params are forwarded **only** to the user-scope sub-fetch.
* **`user.get_profile(user_id, customer_id=None)`**: convenience getter returning a typed `UserProfileModel` (client-defined critical attributes + free-text overview). Raises `ContextNotFoundError` (404) when no profile exists.
* **New typed models**: `TranscriptTurn`, `TranscriptIngestResponse`, `UserProfileModel`, `ProfileAttributeModel`, `ConversationSummaryModel`, all with a `.raw` escape hatch and unknown-field tolerance. `ContextResponse` and `UnifiedContextResponse` gain optional `profile` / `conversations` fields, and `UnifiedContextResponse.format_for_prompt()` renders `## Caller Profile` and `## Previous Conversations` sections when present (byte-identical output when absent).
* **New exceptions**: `ConflictError` and `TranscriptConflictError` (both permanent). `InsufficientCreditsError` is now exported at the top level.

### Changed

* **HTTP 409 and 422 mapping**: the transport now maps **422 → `InvalidInputError`** and **409 → `ConflictError`** (discriminated on a `{"detail": {"code": "transcript_conflict"}}` body to `TranscriptConflictError`). Both are permanent and **never retried**. Previously both status codes fell through to a retryable transient error.
* **`conversation.compact()` 409 semantics** *(behavioral)*: a "Compaction already in progress" 409 now raises a permanent `ConflictError` immediately instead of being retried as a transient error and eventually surfacing as one. Intentional: a 409 here means another compaction already holds the lock, and retrying cannot change that. Catch `ConflictError` (or its base `SynapPermanentError`) where you previously caught the transient/retry-exhausted error.

***

## v0.2.0, 2026-07-06

### Added

* **`precision_level` fetch parameter**: All context fetch calls now accept an optional `precision_level` parameter (`"high"` or `"medium"`). With `"high"` (the default), behavior is unchanged: results go through an additional relevance-refinement pass before being returned. `"medium"` skips the refinement pass for faster responses; recall isn't impacted (the same candidate memories are searched), but outputs are less precisely filtered.

***

## v0.1.2, 2025-01-15

### Added

* **Entity Resolution integration**: The ingestion pipeline now resolves entities across conversations. Mentions of the same entity (e.g., "John", "John Smith", "my manager") are linked to a canonical entity record.
* **Review queue for entity resolution**: Ambiguous entity matches are routed to a review queue for human verification via the Dashboard.
* **Auto-registration of unresolved entities**: New entities that do not match any existing record are automatically registered at the CUSTOMER scope for future lookups.
* **Semantic entity matching**: Entity resolution uses semantic similarity matching, catching variations that exact string matching would miss.

### Changed

* Entity resolution is now integrated before persistence in the ingestion flow.
* Entity resolution runs as a graceful degradation feature: if unavailable, the pipeline continues without resolution and logs a warning.

### Fixed

* Fixed non-deterministic test behavior caused by Python set iteration order in pipeline stage tests.

***

## v0.1.1, 2025-01-10

### Added

* **Memory Architecture Configuration (MACA) system**: Full configuration lifecycle with init, update, review, apply, and rollback operations.
* **Admin API Groups A-D**: Client lifecycle (10 endpoints), instance lifecycle (12 endpoints), config management (10 endpoints), and setup/onboarding (6 endpoints).
* **Dashboard API routes**: Configuration detail and history endpoints for the web UI.
* **Configuration persistence and workflow improvements**: Added storage and workflow support for configuration metadata, approvals, and history.
* **Configuration validation improvements**: Stronger schema and business-rule validation for submitted configuration files.
* **Setup and architecture management improvements**: Better onboarding and dashboard-facing configuration management flows.

### Changed

* Admin API response shapes were standardized for consistency across dashboard routes.
* Configuration version numbers are parsed from semantic version strings ("1.0.0" becomes version `1`).

### Fixed

* Resolved circular import issues in `admin_api/__init__.py` by using lazy imports (inside methods) for cross-manager dependencies.

***

## v0.1.0, 2025-01-05

### Added

* **Initial release** of the Synap SDK and API.
* **Memory ingestion pipeline**: Four-stage async pipeline (extraction, categorization, entity resolution, storage) with `fast` and `long-range` processing modes.
* **Context retrieval**: `POST /v1/context/fetch` with vector search, graph traversal, and re-ranking. Supports `fast` and `accurate` retrieval modes.
* **Context compaction**: `POST /v1/context/compact` with `adaptive`, `aggressive`, `balanced`, and `conservative` strategies.
* **Instance management**: Full CRUD for instances via the Dashboard API, including API key generation and revocation.
* **API key authentication**: `synap_<random>` keys issued from the Dashboard, used as `Authorization: Bearer` for all SDK communication (REST and gRPC).
* **Cloud auth layer**: Production-ready authentication and authorization foundation for SDK and dashboard operations.
* **Memory Architecture Configurators**: Initial configuration system for storage, ingestion, and retrieval controls.
* **Scope system**: Four-level scope chain (USER > CUSTOMER > CLIENT > WORLD) with proper isolation and inheritance.
* **Webhook system**: Five event types (`conversation.started`, `conversation.ended`, `context.retrieved`, `config.applied`, `compaction.completed`) with HMAC-SHA256 signature verification.
* **Analytics**: Usage metrics, latency percentiles, and token tracking with minute/hour/day rollup buckets.
* **Python SDK**: Fully async SDK with typed exceptions and automatic retries.
* **PostgreSQL backend**: Persistent storage for clients, instances, credentials, memories, and analytics data.
* **Production key management integration**: Cloud-integrated key management support.

### Security

* API keys are hashed (SHA-256) at rest and shown to the user only once at generation time.
* Revoking an API key takes effect immediately.
* AuthContext is immutable once created, preventing tampering.

***

<Note>
  Versions prior to 1.0.0 may include breaking changes in minor version increments as the API stabilizes. We recommend pinning to a specific version in production and testing upgrades in staging first.
</Note>
