{
  "schema_version": 2,
  "id": "develop/ai/context-engine/agent-memory/namespaces",
  "title": "Namespaces",
  "url": "https://redis.io/docs/latest/develop/ai/context-engine/agent-memory/namespaces/",
  "summary": "Group session memory and long-term memory with optional namespaces.",
  "tags": [
    "docs",
    "develop",
    "ai"
  ],
  "last_updated": "2026-11-03T10:02:56-08:00",
  "children": [
    {
      "id": "develop/ai/context-engine/agent-memory/namespaces/namespace-routing",
      "summary": "Configure shared namespace routing and admission rules for long-term memories.",
      "title": "Namespace routing",
      "url": "https://redis.io/docs/latest/develop/ai/context-engine/agent-memory/namespaces/namespace-routing/"
    }
  ],
  "page_type": "content",
  "content_hash": "3fc6fc2f3585043e056afebc002ff869d427f89795e1d84869f227c3482c0c2c",
  "sections": [
    {
      "id": "code-examples",
      "title": "Code examples",
      "role": "example",
      "text": "These examples connect to Iris services using SDKs or HTTP requests with curl. Follow one language throughout each walkthrough.\n\n\nNamespaces are optional. Use them to group memories for a project, team, or user. For example, a travel agent can keep a user's trip memories in a personal `example-travel` namespace.\n\nCreate the namespace before writing to it. The response contains a server-generated `namespaceId`. Save this ID and use it as `namespaceId` on session events and long-term memory writes. You will also use this ID to search for memories in that namespace. Names and paths can change when you rename a namespace, but its ID stays the same."
    },
    {
      "id": "create-a-personal-namespace",
      "title": "Create a personal namespace",
      "role": "content",
      "text": "These examples continue from the [quickstart](https://redis.io/docs/latest/develop/ai/context-engine/agent-memory/quickstart). Load the same `.env` connection values and reuse its user ID. Expand an example to copy a complete program that connects for you.\n\nEach run repeats every write in the program. Session-event writes and memory creates with a new idempotency key add new records, so run cleanup or change the identifiers before rerunning.\n\n\nThis example uses a personal namespace to group the trip memories. It creates a personal namespace for the user's travel memories and keeps the returned ID:\n\n**Available in:** Python (Iris), cURL (Iris)\n\n##### Python (Iris)\n\n[code example]\n\n##### cURL (Iris)\n\n[code example]\n\n\n\nSave the ID and reuse it on later runs. Creating the same namespace again returns `409 Conflict`. If you lose the ID, list personal roots with `scope=PERSONAL` and `ownerId` set to the user ID, then find the namespace by name.\n\nStart a new session with this namespace. Extracted memories inherit it:\n\n**Available in:** Python (Iris), cURL (Iris)\n\n##### Python (Iris)\n\n[code example]\n\n##### cURL (Iris)\n\n[code example]"
    },
    {
      "id": "create-a-shared-namespace",
      "title": "Create a shared namespace",
      "role": "content",
      "text": "A shared namespace groups memories that an application uses across users or agents. For example, a travel-planning team can use a shared `example-team-travel` namespace for information that everyone on the team needs. The namespace has `SHARED` scope and no namespace owner. Individual long-term memories still have their own `ownerId` values.\n\nApplications use the same namespace ID when starting sessions or creating long-term memories for the team. Each conversation keeps its own session ID. Memories extracted from those sessions use the shared namespace, so a later search can recall information from several conversations and owners.\n\nYour application decides who can contribute to and retrieve the team's memories. Check the user's access before writing or searching. `SHARED` scope describes how memories are grouped; it does not grant users permission to access them.\n\nCreate the namespace with `scope` set to `SHARED` and no `ownerId`. In Python, `memory.shared_namespace()` returns the ID of the shared namespace with that name, and creates the namespace only if it does not exist. The cURL request creates the namespace directly:\n\n**Available in:** Python (Iris), cURL (Iris)\n\n##### Python (Iris)\n\n[code example]\n\n##### cURL (Iris)\n\n[code example]\n\n\n\nCreating the same root again returns `409 Conflict`. If you lose the ID, list root namespaces with `scope=SHARED` and find `example-team-travel`, or call `memory.shared_namespace()` again.\n\nTo add a conversation to this namespace, use a new session ID and set its first event's namespace ID to the shared ID. Use `memory.conversation(..., namespace_id=shared_namespace_id)` in Python, or set `\"namespaceId\"` on the first event in cURL. For direct long-term memory creation, set the namespace ID on each record. Creating the namespace does not move existing memories into it.\n\nThis example creates one team memory in the shared namespace:\n\n**Available in:** Python (Iris), cURL (Iris)\n\n##### Python (Iris)\n\n[code example]\n\n##### cURL (Iris)\n\n[code example]"
    },
    {
      "id": "recall-shared-memories",
      "title": "Recall shared memories",
      "role": "content",
      "text": "After writing memories to the shared namespace, search with its namespace ID. An empty namespace returns no memories.\n\n`memory.recall()` searches the owner's memories and then each namespace in `shared`. The shared searches have no owner filter, so results can include memories associated with different owners in that namespace. The CLI `--shared` option takes the namespace name. The cURL request searches only the shared namespace. Add an `ownerId` filter when you need only one owner's memories.\n\n**Available in:** Python (Iris), cURL (Iris), CLI (Iris)\n\n##### Python (Iris)\n\n[code example]\n\n##### cURL (Iris)\n\n[code example]\n\n##### CLI (Iris)\n\n[code example]\n\n\n\nThe namespace filter selects that exact namespace. To search its children too, list them and include their IDs with `filter.namespaceId.in`."
    },
    {
      "id": "place-and-retrieve-memories",
      "title": "Place and retrieve memories",
      "role": "content",
      "text": "Pass `\"namespaceId\": \"<namespace-id>\"` on the first event when you start a session. The first event fixes the session namespace. Later events cannot add or change it. Memories extracted from the session use that namespace, so use a new session ID when adding a namespace to the quickstart example.\n\nFor direct long-term memory creation, set `namespaceId` on each record. To move one existing memory, send `PATCH /iris/data/v1/agent-memory/stores/{storeId}/memories/{memoryId}` with only `namespaceId` (`memory.client.update_long_term_memory()` in Python). A namespace-only update keeps the memory's current expiration (TTL):\n\n**Available in:** Python (Iris), cURL (Iris)\n\n##### Python (Iris)\n\n[code example]\n\n##### cURL (Iris)\n\n[code example]\n\n\n\nTo move several memories in one request, use `POST /iris/data/v1/agent-memory/stores/{storeId}/memories/move` (`memory.client.move_long_term_memories()` in Python) with their IDs and the destination `namespaceId`. Both requests run admission checks at the destination. Check both `moved` and `errors` in a bulk move response before treating the batch as complete:\n\n**Available in:** Python (Iris), cURL (Iris)\n\n##### Python (Iris)\n\n[code example]\n\n##### cURL (Iris)\n\n[code example]\n\n\n\nSearch with `filter.namespaceId.eq` for one namespace or `filter.namespaceId.in` for several IDs. These filters match exact namespace IDs; they do not expand a parent into its descendants. List the children and include their IDs when you need to search several levels of a hierarchy. Keep the `ownerId` filter when recalling one user's memories:\n\n**Available in:** Python (Iris), cURL (Iris)\n\n##### Python (Iris)\n\n[code example]\n\n##### cURL (Iris)\n\n[code example]\n\n\n\nYour application must check that the current user can access each namespace before querying it. In on-prem deployments with ownership enforcement enabled, personal namespace access follows the root owner's authenticated user ID. Shared namespaces are accessible to callers with the required store permission. If a shared namespace is only for one team, enforce that rule in your application or use separate stores and grants. See [Authorize every memory request](https://redis.io/docs/latest/develop/ai/context-engine/agent-memory/developer-guide#authorize-every-memory-request)."
    },
    {
      "id": "create-a-namespace-hierarchy",
      "title": "Create a namespace hierarchy",
      "role": "content",
      "text": "Choose a root scope when you create a namespace:\n\n| Scope | Creation fields | Example use |\n|:------|:----------------|:------------|\n| `PERSONAL` | `name`, `scope`, and `ownerId` | A user's travel plans. |\n| `SHARED` | `name` and `scope`, without `ownerId` | Information used across a team. |\n\nCreate a child with `name` and `parentId`. You can also create a hierarchy with `path`, such as `example-travel/kyoto`, and the root scope. Supply `ownerId` for a personal path. Missing path segments are created as needed. Do not combine `path` with `name` or `parentId`.\n\nThis example creates a child of the personal namespace:\n\n**Available in:** Python (Iris), cURL (Iris)\n\n##### Python (Iris)\n\n[code example]\n\n##### cURL (Iris)\n\n[code example]\n\n\n\nThis example creates a personal path. It reuses the existing `example-travel` root and creates the missing `kyoto` segment:\n\n**Available in:** Python (Iris), cURL (Iris)\n\n##### Python (Iris)\n\n[code example]\n\n##### cURL (Iris)\n\n[code example]\n\n\n\nNames and paths are case-sensitive. The path does not encode scope. Use the returned ID to distinguish namespaces that have the same path under different owners or scopes.\n\nList direct children with `parentId`:\n\n**Available in:** Python (Iris), cURL (Iris)\n\n##### Python (Iris)\n\n[code example]\n\n##### cURL (Iris)\n\n[code example]"
    },
    {
      "id": "manage-namespaces",
      "title": "Manage namespaces",
      "role": "content",
      "text": "| Operation | Behavior |\n|:----------|:---------|\n| List | List roots, or pass `parentId` to list direct children. Sort by `id`, `name`, `createdAt`, or `updatedAt` with `sortBy`; `sortOrder` accepts `ASC` or `DESC`. Defaults are `id` and `ASC`. Follow `nextCursor` with the same filters and sort options. |\n| Get | Retrieve the current name, path, scope, and state by ID. |\n| Rename | Update `name`; continue using the same ID for placement and retrieval. |\n| Archive | Set `state` to `ARCHIVED` to stop new children and placements. You cannot unarchive a namespace. |\n| Delete | Delete an empty leaf namespace. A namespace with children or memory placements returns `409 Conflict`. |\n\nCreating a namespace at an occupied location returns `409 Conflict`, including when the existing namespace is archived. Save and reuse the returned ID instead of creating the same namespace on each agent turn. For request fields and error responses, see the [namespace API reference](https://redis.io/docs/latest/develop/ai/context-engine/agent-memory/api-reference#operation/CreateNamespace)."
    },
    {
      "id": "sort-namespaces",
      "title": "Sort namespaces",
      "role": "content",
      "text": "This example lists shared roots by name:\n\n**Available in:** Python (Iris), cURL (Iris)\n\n##### Python (Iris)\n\n[code example]\n\n##### cURL (Iris)\n\n[code example]\n\n\n\nName sorting uses the display name with Redis text collation, rather than the hierarchy path. Equal sort values use namespace ID ascending as a tie-breaker."
    },
    {
      "id": "route-and-admit-shared-memories",
      "title": "Route and admit shared memories",
      "role": "content",
      "text": "An explicit namespace destination must pass its admission rules. Direct creation without a namespace stays unassigned. To route an existing shared memory, omit `namespaceId` from a move request. Personal and unassigned memories are not candidates for automatic routing. See [Namespace routing](https://redis.io/docs/latest/develop/ai/context-engine/agent-memory/namespaces/namespace-routing) for policy setup, examples, and per-item errors."
    },
    {
      "id": "delete-the-example-namespaces",
      "title": "Delete the example namespaces",
      "role": "content",
      "text": "Only an empty leaf namespace can be deleted. This example deletes the example user's session data and long-term memories, then deletes each example namespace after its children. Wait until extraction for the example session finishes first; a namespace that still has memory placements returns `409 Conflict`.\n\n**Available in:** Python (Iris), cURL (Iris)\n\n##### Python (Iris)\n\n[code example]\n\n##### cURL (Iris)\n\n[code example]"
    }
  ],
  "examples": [
    {
      "id": "create-a-personal-namespace-ex0",
      "language": "python",
      "code": "created = memory.client.create_namespace(request={\n    \"name\": \"example-travel\",\n    \"scope\": models.NamespaceScope.PERSONAL,\n    \"owner_id\": OWNER_ID,\n})\nnamespace_id = created.namespace.namespace_id\nprint(\"Personal namespace:\", namespace_id)",
      "section_id": "create-a-personal-namespace"
    },
    {
      "id": "create-a-personal-namespace-ex1",
      "language": "bash",
      "code": "jq -n --arg owner \"$OWNER_ID\" \\\n  '{name: \"example-travel\", scope: \"PERSONAL\", ownerId: $owner}' > namespace.json\nNAMESPACE_ID=$(curl --fail-with-body --silent --show-error \\\n  -X POST \"$MEMORY_API/namespaces\" \\\n  -H \"Authorization: Bearer $IRIS_AGENT_MEMORY_API_KEY\" \\\n  -H 'Content-Type: application/json' --data-binary @namespace.json | jq -er '.namespace.namespaceId')\necho \"Personal namespace: $NAMESPACE_ID\"",
      "section_id": "create-a-personal-namespace"
    },
    {
      "id": "create-a-personal-namespace-ex2",
      "language": "python",
      "code": "conversation = memory.conversation(\n    owner=OWNER_ID,\n    session_id=\"example-travel-namespace-session\",\n    namespace_id=namespace_id,\n)\nconversation.user(\"I am visiting Tokyo and Kyoto next month.\")",
      "section_id": "create-a-personal-namespace"
    },
    {
      "id": "create-a-personal-namespace-ex3",
      "language": "bash",
      "code": "jq -n --arg owner \"$OWNER_ID\" --arg ns \"$NAMESPACE_ID\" \\\n  --arg now \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" --arg key \"$(uuidgen)\" '{\n  actorId: $owner,\n  role: \"USER\",\n  content: [{text: \"I am visiting Tokyo and Kyoto next month.\"}],\n  createdAt: $now,\n  namespaceId: $ns,\n  idempotencyKey: $key\n}' > event.json\ncurl --fail-with-body --silent --show-error \\\n  -X POST \"$MEMORY_API/sessions/example-travel-namespace-session/events\" \\\n  -H \"Authorization: Bearer $IRIS_AGENT_MEMORY_API_KEY\" \\\n  -H 'Content-Type: application/json' --data-binary @event.json | jq .",
      "section_id": "create-a-personal-namespace"
    },
    {
      "id": "create-a-shared-namespace-ex0",
      "language": "python",
      "code": "shared_namespace_id = memory.shared_namespace(\"example-team-travel\")\nprint(\"Shared namespace:\", shared_namespace_id)",
      "section_id": "create-a-shared-namespace"
    },
    {
      "id": "create-a-shared-namespace-ex1",
      "language": "bash",
      "code": "SHARED_NAMESPACE_ID=$(curl --fail-with-body --silent --show-error \\\n  -X POST \"$MEMORY_API/namespaces\" \\\n  -H \"Authorization: Bearer $IRIS_AGENT_MEMORY_API_KEY\" \\\n  -H 'Content-Type: application/json' \\\n  --data '{\"name\": \"example-team-travel\", \"scope\": \"SHARED\"}' | jq -er '.namespace.namespaceId')\necho \"Shared namespace: $SHARED_NAMESPACE_ID\"",
      "section_id": "create-a-shared-namespace"
    },
    {
      "id": "create-a-shared-namespace-ex2",
      "language": "python",
      "code": "memory.remember(\n    \"The team books refundable rail passes for every Japan trip.\",\n    owner=OWNER_ID,\n    namespace_id=shared_namespace_id,\n)",
      "section_id": "create-a-shared-namespace"
    },
    {
      "id": "create-a-shared-namespace-ex3",
      "language": "bash",
      "code": "jq -n --arg owner \"$OWNER_ID\" --arg ns \"$SHARED_NAMESPACE_ID\" --arg key \"$(uuidgen)\" '{\n  memories: [{\n    memoryId: \"example-rail-passes\",\n    ownerId: $owner,\n    namespaceId: $ns,\n    text: \"The team books refundable rail passes for every Japan trip.\"\n  }],\n  idempotencyKey: $key\n}' > memories.json\ncurl --fail-with-body --silent --show-error \\\n  -X POST \"$MEMORY_API/memories\" \\\n  -H \"Authorization: Bearer $IRIS_AGENT_MEMORY_API_KEY\" \\\n  -H 'Content-Type: application/json' --data-binary @memories.json | jq .",
      "section_id": "create-a-shared-namespace"
    },
    {
      "id": "recall-shared-memories-ex0",
      "language": "python",
      "code": "known = memory.recall(\n    \"What travel requirements has the team discussed?\",\n    owner=OWNER_ID,\n    shared=[shared_namespace_id],\n)\nprint(known.as_prompt())",
      "section_id": "recall-shared-memories"
    },
    {
      "id": "recall-shared-memories-ex1",
      "language": "bash",
      "code": "jq -n --arg ns \"$SHARED_NAMESPACE_ID\" '{\n  query: \"What travel requirements has the team discussed?\",\n  filter: {namespaceId: {eq: $ns}},\n  limit: 5\n}' > search.json\ncurl --fail-with-body --silent --show-error \\\n  -X POST \"$MEMORY_API/memories/search\" \\\n  -H \"Authorization: Bearer $IRIS_AGENT_MEMORY_API_KEY\" \\\n  -H 'Content-Type: application/json' --data-binary @search.json | jq '.items[] | {memoryId, ownerId, text}'",
      "section_id": "recall-shared-memories"
    },
    {
      "id": "recall-shared-memories-ex2",
      "language": "bash",
      "code": "set -euo pipefail\n\niris agent-memory memories search \\\n  \"What travel requirements has the team discussed?\" \\\n  --owner quickstart-user --shared example-team-travel --prompt",
      "section_id": "recall-shared-memories"
    },
    {
      "id": "place-and-retrieve-memories-ex0",
      "language": "python",
      "code": "hotel = memory.remember(\n    \"The user is staying at a hotel near Gion in Kyoto.\",\n    owner=OWNER_ID,\n    memory_id=\"example-kyoto-hotel\",\n)\nupdated = memory.client.update_long_term_memory(\n    memory_id=hotel.id, namespace_id=namespace_id,\n)\nprint(updated.memory_id, \"is in\", updated.namespace_id)",
      "section_id": "place-and-retrieve-memories"
    },
    {
      "id": "place-and-retrieve-memories-ex1",
      "language": "bash",
      "code": "jq -n --arg owner \"$OWNER_ID\" --arg key \"$(uuidgen)\" '{\n  memories: [{memoryId: \"example-kyoto-hotel\", ownerId: $owner, text: \"The user is staying at a hotel near Gion in Kyoto.\"}],\n  idempotencyKey: $key\n}' > hotel.json\ncurl --fail-with-body --silent --show-error \\\n  -X POST \"$MEMORY_API/memories\" \\\n  -H \"Authorization: Bearer $IRIS_AGENT_MEMORY_API_KEY\" \\\n  -H 'Content-Type: application/json' --data-binary @hotel.json > /dev/null\ncurl --fail-with-body --silent --show-error \\\n  -X PATCH \"$MEMORY_API/memories/example-kyoto-hotel\" \\\n  -H \"Authorization: Bearer $IRIS_AGENT_MEMORY_API_KEY\" \\\n  -H 'Content-Type: application/json' \\\n  --data \"$(jq -n --arg ns \"$NAMESPACE_ID\" '{namespaceId: $ns}')\" | jq '{memoryId, namespaceId}'",
      "section_id": "place-and-retrieve-memories"
    },
    {
      "id": "place-and-retrieve-memories-ex2",
      "language": "python",
      "code": "arrival = memory.remember(\n    \"The user lands in Tokyo on a Friday evening.\",\n    owner=OWNER_ID,\n    memory_id=\"example-tokyo-arrival\",\n)\nmoved = memory.client.move_long_term_memories(\n    memory_ids=[arrival.id], namespace_id=namespace_id,\n)\nprint(\"Moved:\", moved.moved)\nfor error in moved.errors or []:\n    print(\"Not moved:\", error.memory_id, error.status, error.title)",
      "section_id": "place-and-retrieve-memories"
    },
    {
      "id": "place-and-retrieve-memories-ex3",
      "language": "bash",
      "code": "jq -n --arg owner \"$OWNER_ID\" --arg key \"$(uuidgen)\" '{\n  memories: [{memoryId: \"example-tokyo-arrival\", ownerId: $owner, text: \"The user lands in Tokyo on a Friday evening.\"}],\n  idempotencyKey: $key\n}' > arrival.json\ncurl --fail-with-body --silent --show-error \\\n  -X POST \"$MEMORY_API/memories\" \\\n  -H \"Authorization: Bearer $IRIS_AGENT_MEMORY_API_KEY\" \\\n  -H 'Content-Type: application/json' --data-binary @arrival.json > /dev/null\ncurl --fail-with-body --silent --show-error \\\n  -X POST \"$MEMORY_API/memories/move\" \\\n  -H \"Authorization: Bearer $IRIS_AGENT_MEMORY_API_KEY\" \\\n  -H 'Content-Type: application/json' \\\n  --data \"$(jq -n --arg ns \"$NAMESPACE_ID\" '{memoryIds: [\"example-tokyo-arrival\"], namespaceId: $ns}')\" | jq '{moved, errors}'",
      "section_id": "place-and-retrieve-memories"
    },
    {
      "id": "place-and-retrieve-memories-ex4",
      "language": "python",
      "code": "results = memory.client.search_long_term_memory(request={\n    \"query\": \"Where is the user staying?\",\n    \"filter_\": {\n        \"owner_id\": {\"eq\": OWNER_ID},\n        \"namespace_id\": {\"in\": [namespace_id]},\n    },\n    \"limit\": 5,\n})\nfor record in results.items:\n    print(record.memory_id, record.namespace_id, record.text)",
      "section_id": "place-and-retrieve-memories"
    },
    {
      "id": "place-and-retrieve-memories-ex5",
      "language": "bash",
      "code": "jq -n --arg owner \"$OWNER_ID\" --arg ns \"$NAMESPACE_ID\" '{\n  query: \"Where is the user staying?\",\n  filter: {ownerId: {eq: $owner}, namespaceId: {in: [$ns]}},\n  limit: 5\n}' > placed.json\ncurl --fail-with-body --silent --show-error \\\n  -X POST \"$MEMORY_API/memories/search\" \\\n  -H \"Authorization: Bearer $IRIS_AGENT_MEMORY_API_KEY\" \\\n  -H 'Content-Type: application/json' --data-binary @placed.json | jq '.items[] | {memoryId, namespaceId, text}'",
      "section_id": "place-and-retrieve-memories"
    },
    {
      "id": "create-a-namespace-hierarchy-ex0",
      "language": "python",
      "code": "child = memory.client.create_namespace(request={\n    \"name\": \"japan\",\n    \"parent_id\": namespace_id,\n})\nprint(child.namespace.path, child.namespace.namespace_id)",
      "section_id": "create-a-namespace-hierarchy"
    },
    {
      "id": "create-a-namespace-hierarchy-ex1",
      "language": "bash",
      "code": "curl --fail-with-body --silent --show-error \\\n  -X POST \"$MEMORY_API/namespaces\" \\\n  -H \"Authorization: Bearer $IRIS_AGENT_MEMORY_API_KEY\" \\\n  -H 'Content-Type: application/json' \\\n  --data \"$(jq -n --arg parent \"$NAMESPACE_ID\" '{name: \"japan\", parentId: $parent}')\" | jq '.namespace | {path, namespaceId}'",
      "section_id": "create-a-namespace-hierarchy"
    },
    {
      "id": "create-a-namespace-hierarchy-ex2",
      "language": "python",
      "code": "leaf = memory.client.create_namespace(request={\n    \"path\": \"example-travel/kyoto\",\n    \"scope\": models.NamespaceScope.PERSONAL,\n    \"owner_id\": OWNER_ID,\n})\nprint(leaf.namespace.path, leaf.namespace.namespace_id)",
      "section_id": "create-a-namespace-hierarchy"
    },
    {
      "id": "create-a-namespace-hierarchy-ex3",
      "language": "bash",
      "code": "curl --fail-with-body --silent --show-error \\\n  -X POST \"$MEMORY_API/namespaces\" \\\n  -H \"Authorization: Bearer $IRIS_AGENT_MEMORY_API_KEY\" \\\n  -H 'Content-Type: application/json' \\\n  --data \"$(jq -n --arg owner \"$OWNER_ID\" '{path: \"example-travel/kyoto\", scope: \"PERSONAL\", ownerId: $owner}')\" | jq '.namespace | {path, namespaceId}'",
      "section_id": "create-a-namespace-hierarchy"
    },
    {
      "id": "create-a-namespace-hierarchy-ex4",
      "language": "python",
      "code": "children = memory.client.list_namespaces(parent_id=namespace_id)\nfor item in children.items:\n    print(item.path, item.namespace_id, item.state)",
      "section_id": "create-a-namespace-hierarchy"
    },
    {
      "id": "create-a-namespace-hierarchy-ex5",
      "language": "bash",
      "code": "curl --fail-with-body --silent --show-error --get \\\n  \"$MEMORY_API/namespaces\" \\\n  -H \"Authorization: Bearer $IRIS_AGENT_MEMORY_API_KEY\" \\\n  --data-urlencode \"parentId=$NAMESPACE_ID\" | jq '.items[] | {path, namespaceId, state}'",
      "section_id": "create-a-namespace-hierarchy"
    },
    {
      "id": "sort-namespaces-ex0",
      "language": "python",
      "code": "namespaces = memory.client.list_namespaces(\n    scope=models.NamespaceScope.SHARED,\n    sort_by=models.NamespaceSortBy.NAME,\n    sort_order=models.NamespaceSortOrder.ASC,\n    limit=20,\n)\nfor item in namespaces.items:\n    print(item.name, item.namespace_id)\nprint(\"Next cursor:\", namespaces.next_cursor)",
      "section_id": "sort-namespaces"
    },
    {
      "id": "sort-namespaces-ex1",
      "language": "bash",
      "code": "curl --fail-with-body --silent --show-error --get \\\n  \"$MEMORY_API/namespaces\" \\\n  -H \"Authorization: Bearer $IRIS_AGENT_MEMORY_API_KEY\" \\\n  --data-urlencode 'scope=SHARED' --data-urlencode 'limit=20' \\\n  --data-urlencode 'sortBy=name' --data-urlencode 'sortOrder=ASC' | jq '{names: [.items[].name], nextCursor}'",
      "section_id": "sort-namespaces"
    },
    {
      "id": "delete-the-example-namespaces-ex0",
      "language": "python",
      "code": "forgotten = memory.forget(OWNER_ID)\nprint(f\"Deleted {forgotten.sessions} sessions and {forgotten.memories} memories\")\n\n\ndef delete_tree(namespace_id):\n    # Only an empty leaf can be deleted, so remove children first.\n    for child in memory.client.list_namespaces(parent_id=namespace_id).items:\n        delete_tree(child.namespace_id)\n    memory.client.delete_namespace(namespace_id=namespace_id)\n\n\npersonal = memory.client.list_namespaces(\n    scope=models.NamespaceScope.PERSONAL, owner_id=OWNER_ID,\n)\nshared, cursor = [], None\nwhile True:\n    page = memory.client.list_namespaces(\n        scope=models.NamespaceScope.SHARED, limit=200, cursor=cursor,\n    )\n    shared += page.items\n    cursor = page.next_cursor\n    if not cursor:\n        break\n\nfor root in [*personal.items, *shared]:\n    if root.name in (\"example-travel\", \"example-team-travel\"):\n        delete_tree(root.namespace_id)\n        print(\"Deleted\", root.path)",
      "section_id": "delete-the-example-namespaces"
    },
    {
      "id": "delete-the-example-namespaces-ex1",
      "language": "bash",
      "code": "AUTH=\"Authorization: Bearer $IRIS_AGENT_MEMORY_API_KEY\"\n\ncurl --fail-with-body --silent --show-error -X DELETE \\\n  \"$MEMORY_API/sessions/example-travel-namespace-session\" -H \"$AUTH\"\n\njq -n --arg owner \"$OWNER_ID\" '{filter: {ownerId: {eq: $owner}}, limit: 100}' > owned.json\nIDS=$(curl --fail-with-body --silent --show-error -X POST \"$MEMORY_API/memories/search\" \\\n  -H \"$AUTH\" -H 'Content-Type: application/json' --data-binary @owned.json | jq -c '[.items[].memoryId]')\nif [ \"$IDS\" != \"[]\" ]; then\n  curl --fail-with-body --silent --show-error -X POST \"$MEMORY_API/memories/bulk-delete\" \\\n    -H \"$AUTH\" -H 'Content-Type: application/json' \\\n    --data \"$(jq -n --argjson ids \"$IDS\" '{memoryIds: $ids}')\" | jq .\nfi\n\ndelete_tree() {  # only an empty leaf can be deleted, so remove children first\n  local child\n  for child in $(curl --fail-with-body --silent --show-error --get \"$MEMORY_API/namespaces\" \\\n      -H \"$AUTH\" --data-urlencode \"parentId=$1\" | jq -r '.items[].namespaceId'); do\n    delete_tree \"$child\"\n  done\n  curl --fail-with-body --silent --show-error -X DELETE \"$MEMORY_API/namespaces/$1\" -H \"$AUTH\"\n  echo \"Deleted $1\"\n}\n\nPERSONAL_ID=$(curl --fail-with-body --silent --show-error --get \"$MEMORY_API/namespaces\" -H \"$AUTH\" \\\n  --data-urlencode 'scope=PERSONAL' --data-urlencode \"ownerId=$OWNER_ID\" \\\n  | jq -r '.items[] | select(.name == \"example-travel\") | .namespaceId')\nSHARED_ID=$(curl --fail-with-body --silent --show-error --get \"$MEMORY_API/namespaces\" -H \"$AUTH\" \\\n  --data-urlencode 'scope=SHARED' --data-urlencode 'limit=200' \\\n  | jq -r '.items[] | select(.name == \"example-team-travel\") | .namespaceId')\nfor id in $PERSONAL_ID $SHARED_ID; do\n  delete_tree \"$id\"\ndone",
      "section_id": "delete-the-example-namespaces"
    }
  ]
}
