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

# Memory API: Iterate and Refine Existing Brand Generations

> Use Nomiq Memory Nodes to reference prior generations and refine brand assets iteratively, preserving style seeds without restarting from a blank prompt.

Every successful generation job in Nomiq produces a **Memory Node** — a persisted context object that captures the prompt, the derived style seed, and the structural decisions the AI Engine made during that run. By passing a Memory Node's ID into a subsequent generation call, you instruct the engine to load the prior stylistic context and treat your new prompt as a refinement instruction rather than a fresh creative brief. This is the primary mechanism for iterative brand work: adjusting colors while keeping the logo form, tightening voice while preserving visual identity, or generating multiple client-facing variations from a single approved root.

## How Memory IDs Are Returned

Memory Nodes are created automatically at the end of every successful generation job. You do not call a separate endpoint to create them. The `memory_id` for a completed job is returned inside the `generation.success` webhook payload under `data.memory_id`:

```json theme={null}
{
  "event_id": "evt_5k6l7m8n",
  "type": "generation.success",
  "created_at": 1677649428,
  "data": {
    "job_id": "job_9x8y7z6w",
    "project_id": "proj_1A2b3C4d5E",
    "memory_id": "mem_X1y2Z3w4",
    "assets": {
      "logo_svg": "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>...</svg>",
      "primary_color": "#4338ca",
      "secondary_color": "#faf7f0",
      "font_family": "Inter"
    }
  }
}
```

Store the `memory_id` value (`mem_X1y2Z3w4` in this example) in your database alongside the job record. You will pass it back to the Generation API in any subsequent refinement calls.

***

## Iterating with a Memory ID

To refine an existing generation, include the `memory_id` parameter in the body of a new `POST /v1/brands/generate` request. The new `prompt` should describe only the change you want — you do not need to repeat the entire original brief.

### The `memory_id` Parameter on Generate

<ParamField body="memory_id" type="string">
  The unique identifier of an existing Memory Node (prefix `mem_`) from a previous successful generation. When provided, the AI Engine loads the referenced stylistic context and applies the new `prompt` as an incremental refinement. The resulting job produces a new Memory Node, allowing you to chain refinements in sequence. If omitted, the generation starts from scratch using only the provided `prompt`.
</ParamField>

### Example: Iterative Refinement

The following example shows a two-step workflow. The first call creates the initial brand identity for a coffee shop. The second call references the resulting Memory Node to adjust only the typography, while preserving the indigo color palette and logo form established in step one.

**Step 1 — Initial generation:**

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.nomiq.com/v1/brands/generate" \
    -H "Authorization: Bearer sk_live_xxx" \
    -H "Content-Type: application/json" \
    -d '{
      "project_id": "proj_1A2b3C4d5E",
      "prompt": "A modern coffee shop in Brooklyn that specializes in cold brew. Minimalistic cold brew glass logo, deep indigo and warm cream palette, clean geometric sans-serif typography.",
      "webhook_url": "https://yourapp.com/api/nomiq/webhook"
    }'
  ```

  ```javascript Node.js theme={null}
  // Step 1: dispatch the initial generation
  const initialResponse = await fetch("https://api.nomiq.com/v1/brands/generate", {
    method: "POST",
    headers: {
      "Authorization": "Bearer sk_live_xxx",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      project_id: "proj_1A2b3C4d5E",
      prompt:
        "A modern coffee shop in Brooklyn that specializes in cold brew. " +
        "Minimalistic cold brew glass logo, deep indigo and warm cream palette, " +
        "clean geometric sans-serif typography.",
      webhook_url: "https://yourapp.com/api/nomiq/webhook",
    }),
  });

  const initialJob = await initialResponse.json();
  // Save initialJob.id — you will receive memory_id via webhook
  ```

  ```python Python theme={null}
  import requests

  # Step 1: dispatch the initial generation
  initial_response = requests.post(
      "https://api.nomiq.com/v1/brands/generate",
      headers={
          "Authorization": "Bearer sk_live_xxx",
          "Content-Type": "application/json",
      },
      json={
          "project_id": "proj_1A2b3C4d5E",
          "prompt": (
              "A modern coffee shop in Brooklyn that specializes in cold brew. "
              "Minimalistic cold brew glass logo, deep indigo and warm cream palette, "
              "clean geometric sans-serif typography."
          ),
          "webhook_url": "https://yourapp.com/api/nomiq/webhook",
      },
  )

  initial_job = initial_response.json()
  # Save initial_job["id"] — you will receive memory_id via webhook
  ```
</CodeGroup>

After the `generation.success` webhook fires, you receive `memory_id: "mem_X1y2Z3w4"`. Now use that ID to refine the typography in a second call:

**Step 2 — Refine typography using the Memory Node:**

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.nomiq.com/v1/brands/generate" \
    -H "Authorization: Bearer sk_live_xxx" \
    -H "Content-Type: application/json" \
    -d '{
      "project_id": "proj_1A2b3C4d5E",
      "prompt": "Change the typography to a humanist serif. Keep the logo and color palette exactly as they are.",
      "memory_id": "mem_X1y2Z3w4",
      "webhook_url": "https://yourapp.com/api/nomiq/webhook"
    }'
  ```

  ```javascript Node.js theme={null}
  // Step 2: refine typography — preserve logo and palette via memory_id
  const refinedResponse = await fetch("https://api.nomiq.com/v1/brands/generate", {
    method: "POST",
    headers: {
      "Authorization": "Bearer sk_live_xxx",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      project_id: "proj_1A2b3C4d5E",
      prompt:
        "Change the typography to a humanist serif. " +
        "Keep the logo and color palette exactly as they are.",
      memory_id: "mem_X1y2Z3w4", // ID from the generation.success webhook
      webhook_url: "https://yourapp.com/api/nomiq/webhook",
    }),
  });

  const refinedJob = await refinedResponse.json();
  // refinedJob.status === "queued"
  // A new memory_id will be returned in the next generation.success webhook
  ```

  ```python Python theme={null}
  import requests

  # Step 2: refine typography — preserve logo and palette via memory_id
  refined_response = requests.post(
      "https://api.nomiq.com/v1/brands/generate",
      headers={
          "Authorization": "Bearer sk_live_xxx",
          "Content-Type": "application/json",
      },
      json={
          "project_id": "proj_1A2b3C4d5E",
          "prompt": (
              "Change the typography to a humanist serif. "
              "Keep the logo and color palette exactly as they are."
          ),
          "memory_id": "mem_X1y2Z3w4",  # ID from the generation.success webhook
          "webhook_url": "https://yourapp.com/api/nomiq/webhook",
      },
  )

  refined_job = refined_response.json()
  # refined_job["status"] == "queued"
  # A new memory_id will be returned in the next generation.success webhook
  ```
</CodeGroup>

Each generation call that includes a `memory_id` produces its own new Memory Node. This means you can chain refinements in a linear sequence — or branch multiple times from the same parent node to produce parallel variations.

***

## Use Cases

Memory is most valuable when you need to make targeted adjustments without disrupting everything the AI Engine established in a prior run. Common patterns include:

| Goal                                     | Prompt Strategy                                                                        |
| ---------------------------------------- | -------------------------------------------------------------------------------------- |
| Refine colors while keeping the logo     | `"Shift the primary color from indigo to forest green. Preserve the logo form."`       |
| Adjust brand voice while keeping visuals | `"Rewrite the tagline and font pairing to feel more playful. Keep all visual assets."` |
| Generate light and dark mode variants    | `"Produce a dark-mode version of the palette. Logo and typography stay the same."`     |
| Create size-specific logo variants       | `"Generate a compact wordmark variant suitable for 32×32 px favicons."`                |

<Tip>
  Memory is especially powerful in **client revision workflows**. When a client approves a logo but requests color changes, branch a new generation from the approved Memory Node rather than re-running from scratch. This preserves billable approval milestones as discrete nodes in the graph and gives you a clean audit trail of every revision. Because Nomiq's Memory graph is acyclic, you can also dispatch multiple parallel branches from the same approved node — for example, three color palette variations — and present them simultaneously to the client for a single round of feedback.
</Tip>

***

## Listing Memory Nodes for a Project

`GET https://api.nomiq.com/v1/projects/{project_id}/memory`

Returns a chronologically ordered list of all Memory Nodes belonging to a project, most recent first. Use this endpoint to inspect the full revision history of a project or to look up a `memory_id` you did not store at webhook delivery time.

<ParamField path="project_id" type="string" required>
  The unique identifier of the project whose Memory Nodes you want to list.
</ParamField>

<ParamField query="limit" type="integer">
  Maximum number of Memory Nodes to return. Defaults to `10`, maximum `100`.
</ParamField>

<ParamField query="starting_after" type="string">
  A Memory Node ID cursor for pagination. Returns the page of results after this node.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.nomiq.com/v1/projects/proj_1A2b3C4d5E/memory?limit=5" \
    -H "Authorization: Bearer sk_live_xxx"
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.nomiq.com/v1/projects/proj_1A2b3C4d5E/memory?limit=5",
    {
      headers: { Authorization: "Bearer sk_live_xxx" },
    }
  );

  const history = await response.json();
  history.data.forEach((node) => {
    console.log(node.id, node.prompt);
  });
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.nomiq.com/v1/projects/proj_1A2b3C4d5E/memory",
      headers={"Authorization": "Bearer sk_live_xxx"},
      params={"limit": 5},
  )

  history = response.json()
  for node in history["data"]:
      print(node["id"], node["prompt"])
  ```
</CodeGroup>

```json theme={null}
{
  "object": "list",
  "data": [
    {
      "id": "mem_L9m8N7o6",
      "object": "memory_node",
      "prompt": "Change the typography to a humanist serif. Keep the logo and color palette exactly as they are.",
      "parent_id": "mem_X1y2Z3w4",
      "created_at": 1677649500
    },
    {
      "id": "mem_X1y2Z3w4",
      "object": "memory_node",
      "prompt": "A modern coffee shop in Brooklyn that specializes in cold brew. Minimalistic cold brew glass logo, deep indigo and warm cream palette, clean geometric sans-serif typography.",
      "parent_id": null,
      "created_at": 1677649420
    }
  ],
  "has_more": false,
  "next_cursor": null
}
```

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Generation API" icon="bolt" href="/api-reference/generation">
    Dispatch brand generation jobs and pass `memory_id` to iterate on existing outputs.
  </Card>

  <Card title="Prompt Engineering" icon="terminal" href="/ai-engine/prompt-engineering">
    Learn how to write effective refinement prompts that work well with Memory Nodes.
  </Card>
</CardGroup>
