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

# Memory Provenance

> Track where memories came from, which service wrote them, and how conflicts are resolved.

Provenance answers three questions about a memory:

* **Who wrote it?** Which service, API key, Passport agent, or organisation connection observed the claim.
* **Where did it come from?** Which source event, payload hash, and evidence references produced it.
* **Why is this version active?** Which authority, recency, confidence, or human decision selected it over another claim.

This is the governance layer behind MemoryOS. It matters most when multiple services or agents write memories about the same user.

## Core objects

### Service Writer

A Service Writer is a named identity for one backend service. Register one writer for each service that observes user facts.

Examples:

* `support-service`
* `billing-service`
* `crm-sync`
* `learning-platform`

| Field             | Meaning                                            |
| ----------------- | -------------------------------------------------- |
| `service_key`     | Stable slug, for example `billing-service`         |
| `display_name`    | Human-readable label in dashboards                 |
| `authority_rules` | Priority scores per memory category                |
| `api_key_id`      | Optional bound API key for credential verification |

### Source event

A source event is created for an `add()` call that includes a `source` block. It records:

* your system event ID
* when your system observed the event
* which service wrote it
* SHA-256 payload hash
* optional evidence references
* optional scope metadata

Every memory created by that job points back to the source event.

### Claim revision ledger

MemoryOS keeps claim revisions so conflict resolution does not erase history. When a newer or more trusted claim supersedes an older one, the older claim is archived instead of deleted.

The active memory is what retrieval sees. The ledger keeps the full lineage for audit, dashboard inspection, and future graph work.

## Register a Service Writer

```http theme={null}
POST /v1/tenant/service-writers
Authorization: ApiKey mem_live_xxx
Content-Type: application/json
```

```json theme={null}
{
  "service_key": "billing-service",
  "display_name": "Billing Service",
  "authority_rules": {
    "default_priority": 50,
    "categories": {
      "fact": 80,
      "preference": 40,
      "goal": 50
    }
  }
}
```

Use separate API keys per service in production. Bind each writer to its key from the Tenant Dashboard when you are ready for production traffic.

## Send source metadata on `add()`

```http theme={null}
POST /v1/memories/add
Authorization: ApiKey mem_live_xxx
Content-Type: application/json
```

```json theme={null}
{
  "external_user_id": "customer_123",
  "messages": [
    {
      "role": "user",
      "content": "What plan am I currently using?"
    },
    {
      "role": "assistant",
      "content": "Your current subscription plan is Growth."
    }
  ],
  "source": {
    "service": "billing-service",
    "event_id": "billing-plan-2026-06-30-001",
    "observed_at": "2026-06-30T10:00:00Z",
    "scope": {
      "workspace_id": "ws_123"
    },
    "evidence": [
      {
        "source_type": "subscription_record",
        "reference": "billing/subscriptions/ws_123"
      }
    ]
  }
}
```

| Field         | Required | Notes                                                        |
| ------------- | -------- | ------------------------------------------------------------ |
| `service`     | Yes      | Registered `service_key`                                     |
| `event_id`    | Yes      | Stable event ID from your system                             |
| `observed_at` | No       | Defaults to request time if omitted                          |
| `scope`       | No       | JSON metadata such as workspace, region, channel, or ticket  |
| `evidence`    | No       | References to records in your system; do not include secrets |

## Idempotency and payload safety

Retrying the same `source.event_id` with the same payload returns the original job path and does not duplicate extraction.

Retrying the same `source.event_id` with different messages returns a provenance conflict error. This prevents accidental mutation of historical source events.

Raw extraction payloads can be redacted after the configured retention window. The payload hash stays so the source event remains verifiable.

## Conflict resolution

When two writers produce conflicting memories for the same user, MemoryOS compares claims using this order:

1. Writer authority for the memory category
2. Source `observed_at` recency
3. Extraction confidence
4. Human review when equally trusted sources disagree

Example authority rules:

```json theme={null}
{
  "default_priority": 50,
  "categories": {
    "fact": 90,
    "preference": 40
  }
}
```

A billing service can be trusted more for subscription facts, while a chat service may be trusted more for user preferences.

## Equal-authority conflicts

If equally trusted services disagree, MemoryOS does not silently choose one. It creates a review item.

Example:

* Support Service reports: `User's current subscription plan is Starter.`
* Billing Service reports: `User's current subscription plan is Growth.`

If both have equal authority, the tenant dashboard shows the conflict for review. If it is a personal Memory Passport conflict, it appears in the user's Pending Questions tab.

The losing claim is not hard-deleted. It is kept in the revision ledger and marked inactive or archived.

## Provenance in retrieve responses

`retrieve` and `list` include provenance when available:

```json theme={null}
{
  "content": "User's current subscription plan is Growth.",
  "category": "fact",
  "source_event_id": "3c3994d0-1c1d-4e1a-9fd1-0f87f82d13da",
  "provenance": {
    "service": "billing-service",
    "event_id": "billing-plan-2026-06-30-001",
    "observed_at": "2026-06-30T10:00:00Z",
    "received_at": "2026-06-30T10:00:02Z",
    "payload_hash": "7ba8601d36046350e1311f08b7a66646338ee75e3b443ebaba35de9607b6e169",
    "scope": {
      "workspace_id": "ws_123"
    }
  }
}
```

Legacy memories may have partial provenance. The Operator Console shows provenance coverage and unattributed lineage so the MemoryOS team can backfill safely.

## Inspect source events

```http theme={null}
GET /v1/tenant/source-events?external_user_id=customer_123&source_service=billing-service&limit=50
Authorization: ApiKey mem_live_xxx
```

Use this endpoint to inspect source events, payload hashes, linked extraction jobs, evidence references, and scope metadata.

## Error codes

| Code       | Meaning                                                                    |
| ---------- | -------------------------------------------------------------------------- |
| `PROV_403` | API key does not match the writer's bound key                              |
| `PROV_404` | Service writer not found                                                   |
| `PROV_409` | Source event exists with a different payload, or writer key already exists |
| `PROV_422` | Invalid service writer or source payload                                   |

## Who needs provenance?

| Scenario                                    | Need provenance? |
| ------------------------------------------- | ---------------- |
| One simple app writing memories             | Optional         |
| Multiple services writing for the same user | Yes              |
| Compliance audit trail                      | Yes              |
| Exactly-once ingestion with retries         | Yes              |
| Conflict resolution between services        | Yes              |
| Memory Passport shared context              | Yes              |

## Related pages

* [Extraction Quality Loop](/concepts/extraction-quality)
* [Memory Lifecycle and Versioning](/concepts/memory-lifecycle)
* [POST /v1/memories/add](/api-reference/add)
* [POST /v1/memories/retrieve](/api-reference/retrieve)
