{
  "openapi": "3.0.3",
  "info": {
    "title": "MythOS v3 Internal API",
    "description": "Agent-facing API for MythOS memo library operations, community browsing, embedding, and chat.",
    "version": "1.1.0"
  },
  "servers": [
    {
      "url": "https://mythos.one",
      "description": "MythOS v3"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-mythos-key",
        "description": "Internal API key for agent authentication"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "error": {
            "type": "string"
          }
        },
        "required": [
          "success",
          "error"
        ]
      },
      "MemoSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "snippet": {
            "type": "string"
          },
          "visibility": {
            "type": "string",
            "enum": [
              "public",
              "link",
              "private"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "collaboratorTags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "author": {
            "type": "object",
            "properties": {
              "username": {
                "type": "string"
              },
              "displayName": {
                "type": "string"
              }
            }
          },
          "createdAt": {
            "type": "number",
            "nullable": true
          },
          "createdAtIso": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "updatedAt": {
            "type": "number",
            "nullable": true
          },
          "updatedAtIso": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "content": {
            "type": "string"
          },
          "collaboratorContent": {
            "type": "string"
          },
          "seoTitle": {
            "type": "string",
            "nullable": true,
            "maxLength": 70
          },
          "seoDescription": {
            "type": "string",
            "nullable": true,
            "maxLength": 160
          }
        }
      },
      "MemoInput": {
        "type": "object",
        "required": [
          "title"
        ],
        "properties": {
          "title": {
            "type": "string",
            "description": "Memo title"
          },
          "content": {
            "type": "string",
            "description": "Memo content in markdown. Hashtag chips are serialized as [#name](/tag/name); plain #word text is not converted to a tag."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tags for the memo. If omitted, tags are extracted from content."
          },
          "visibility": {
            "type": "string",
            "enum": [
              "public",
              "link",
              "private"
            ],
            "default": "link",
            "description": "Memo visibility level"
          },
          "collaboratorContent": {
            "type": "string",
            "description": "Notes/collaborator section content displayed separately below the memo body"
          },
          "seoTitle": {
            "type": "string",
            "nullable": true,
            "maxLength": 70,
            "description": "Optional <title>/og:title override for public memo pages"
          },
          "seoDescription": {
            "type": "string",
            "nullable": true,
            "maxLength": 160,
            "description": "Optional <meta name=\"description\">/og:description override"
          },
          "sourceMarkupVersion": {
            "type": "integer",
            "description": "Optional. Markup version of the content being sent. Omit (or 1) for legacy behavior — bare #word is auto-linked into a tag. Set to 2 when the content is already v2 markdown where bare #word is literal text and tags are written as [#name](/tag/name)."
          }
        }
      },
      "Memo": {
        "type": "object",
        "properties": {
          "_id": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "visibility": {
            "type": "string"
          },
          "author": {
            "type": "object",
            "properties": {
              "username": {
                "type": "string"
              },
              "uid": {
                "type": "string"
              },
              "displayName": {
                "type": "string"
              }
            }
          },
          "header": {
            "type": "object",
            "properties": {
              "createdAt": {
                "type": "number"
              },
              "updatedAt": {
                "type": "number"
              },
              "title": {
                "type": "string"
              }
            }
          },
          "content": {
            "type": "string"
          },
          "collaboratorContent": {
            "type": "string"
          },
          "contentVersion": {
            "type": "integer"
          },
          "seoTitle": {
            "type": "string",
            "nullable": true,
            "maxLength": 70
          },
          "seoDescription": {
            "type": "string",
            "nullable": true,
            "maxLength": 160
          }
        }
      },
      "CommunitySummary": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Community URL identifier"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "memberCount": {
            "type": "integer"
          },
          "postCount": {
            "type": "integer"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "CommunityPost": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "snippet": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "author": {
            "type": "object",
            "properties": {
              "displayName": {
                "type": "string"
              },
              "username": {
                "type": "string"
              }
            }
          },
          "score": {
            "type": "integer"
          },
          "submittedAt": {
            "type": "number"
          },
          "postSlug": {
            "type": "string"
          }
        }
      }
    }
  },
  "paths": {
    "/api/internal/memos": {
      "get": {
        "summary": "List memos",
        "description": "Returns memos from the library, filtered by query parameters. Results are sorted by last updated descending.",
        "operationId": "listMemos",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "Search query to filter memos by title",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tags",
            "in": "query",
            "description": "Comma-separated tag names to filter by",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "visibility",
            "in": "query",
            "description": "Comma-separated visibility filter (public, link)",
            "schema": {
              "type": "string",
              "default": "public,link"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of memos to return (1-200, default 50)",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of memos",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "memos": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/MemoSummary"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a memo",
        "description": "Creates a new memo in the library. If tags are not provided, they are automatically extracted from the content.",
        "operationId": "createMemo",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemoInput"
              },
              "example": {
                "title": "My New Memo",
                "content": "This is the memo content with [#tags](/tag/tags) inline.",
                "visibility": "link"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Memo created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "memo": {
                      "$ref": "#/components/schemas/Memo"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input (missing title)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update a memo",
        "description": "Updates content and optionally other fields of an existing memo. Increments contentVersion. Optional SEO fields (seoTitle, seoDescription) can be included alongside content. For SEO-only updates without touching content, use PATCH /api/internal/memos/seo instead.",
        "operationId": "updateMemo",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "description": "The memo ID to update",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "content"
                ],
                "properties": {
                  "content": {
                    "type": "string",
                    "description": "Updated memo content (required). Hashtag chips are serialized as [#name](/tag/name); plain #word text is not converted to a tag."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Updated tags. If omitted, tags are extracted from content."
                  },
                  "collaboratorContent": {
                    "type": "string",
                    "description": "Updated notes/collaborator section. Bumps collabContentVersion when provided."
                  },
                  "seoTitle": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 70,
                    "description": "Optional SEO title. Pass null or empty string to clear."
                  },
                  "seoDescription": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 160,
                    "description": "Optional SEO description. Pass null or empty string to clear."
                  },
                  "sourceMarkupVersion": {
                    "type": "integer",
                    "description": "Optional. Markup version of the content being sent. Omit (or 1) for legacy behavior — bare #word is auto-linked into a tag. Set to 2 when the content is already v2 markdown where bare #word is literal text and tags are written as [#name](/tag/name)."
                  }
                }
              },
              "example": {
                "content": "Updated content with new [#tags](/tag/tags)",
                "tags": [
                  "tags",
                  "updated"
                ],
                "seoTitle": "A better title for search engines"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Memo updated successfully. contentVersion reflects the new bumped value.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "contentVersion": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing id, invalid field value, or no updatable field provided",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Memo not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/internal/memos/seo": {
      "patch": {
        "summary": "Update memo SEO metadata",
        "description": "Updates only the seoTitle and/or seoDescription of a memo. Does not touch content, tags, or contentVersion. Pass null or empty string for a field to clear it.",
        "operationId": "updateMemoSeo",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "description": "The memo ID to update",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "At least one of seoTitle or seoDescription is required.",
                "properties": {
                  "seoTitle": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 70,
                    "description": "SEO title override. Pass null or empty string to clear."
                  },
                  "seoDescription": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 160,
                    "description": "SEO description override. Pass null or empty string to clear."
                  }
                }
              },
              "example": {
                "seoTitle": "A better title for search engines",
                "seoDescription": "Up to 160 characters describing this memo for previews."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "SEO metadata updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "seoTitle": {
                      "type": "string",
                      "nullable": true
                    },
                    "seoDescription": {
                      "type": "string",
                      "nullable": true
                    },
                    "updatedAt": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing id, invalid JSON body, no SEO field provided, or invalid field value",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Memo not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/internal/memos/batch": {
      "post": {
        "summary": "Batch create memos",
        "description": "Creates multiple memos in a single operation. Maximum 50 memos per request.",
        "operationId": "batchCreateMemos",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "memos"
                ],
                "properties": {
                  "memos": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/MemoInput"
                    },
                    "maxItems": 50
                  },
                  "sourceMarkupVersion": {
                    "type": "integer",
                    "description": "Optional batch-level markup version applied to every memo that does not set its own. See MemoInput.sourceMarkupVersion."
                  }
                }
              },
              "example": {
                "memos": [
                  {
                    "title": "First Memo",
                    "content": "Content one"
                  },
                  {
                    "title": "Second Memo",
                    "content": "Content two",
                    "tags": [
                      "batch"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Memos created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "created": {
                      "type": "integer"
                    },
                    "memos": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Memo"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/internal/embed": {
      "post": {
        "summary": "Trigger memo embedding",
        "description": "Generates vector embeddings for specified memos or all memos. Used for semantic search.",
        "operationId": "embedMemos",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "required": [
                      "memoIds"
                    ],
                    "properties": {
                      "memoIds": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Array of memo IDs to embed"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "all"
                    ],
                    "properties": {
                      "all": {
                        "type": "boolean",
                        "enum": [
                          true
                        ],
                        "description": "Set to true to embed all memos"
                      }
                    }
                  }
                ]
              },
              "examples": {
                "byIds": {
                  "summary": "Embed specific memos",
                  "value": {
                    "memoIds": [
                      "brianswichkow-abc123",
                      "brianswichkow-def456"
                    ]
                  }
                },
                "all": {
                  "summary": "Embed all memos",
                  "value": {
                    "all": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Embedding results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "embedded": {
                      "type": "integer",
                      "description": "Number of memos successfully embedded"
                    },
                    "failed": {
                      "type": "integer",
                      "description": "Number of memos that failed to embed"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/internal/embed/batch": {
      "post": {
        "summary": "Batch embed memos",
        "description": "Generates vector embeddings for a batch of memos. Maximum 100 memo IDs per request. Returns detailed error information for any failures.",
        "operationId": "batchEmbedMemos",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "memoIds"
                ],
                "properties": {
                  "memoIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 100,
                    "description": "Array of memo IDs to embed"
                  }
                }
              },
              "example": {
                "memoIds": [
                  "brianswichkow-abc123",
                  "brianswichkow-def456"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Batch embedding results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "embedded": {
                      "type": "integer"
                    },
                    "failed": {
                      "type": "integer"
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "memoId": {
                            "type": "string"
                          },
                          "error": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/chat": {
      "post": {
        "summary": "Chat with a library",
        "description": "Send a message to chat with a user's memo library. Uses RAG to find relevant memos and streams an AI response. Supports conversation threading.",
        "operationId": "chatWithLibrary",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "libraryOwnerUsername",
                  "message"
                ],
                "properties": {
                  "libraryOwnerUsername": {
                    "type": "string",
                    "description": "Username of the library owner to chat with"
                  },
                  "message": {
                    "type": "string",
                    "description": "The user's message"
                  },
                  "threadId": {
                    "type": "string",
                    "description": "Optional thread ID for continuing a conversation"
                  }
                }
              },
              "example": {
                "libraryOwnerUsername": "brianswichkow",
                "message": "What are your thoughts on AI?",
                "threadId": "abc-123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "SSE stream of AI response",
            "headers": {
              "X-Thread-Id": {
                "description": "The thread ID for this conversation",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Missing required fields",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Library owner not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/internal/openapi": {
      "get": {
        "summary": "Get OpenAPI specification",
        "description": "Returns this OpenAPI JSON specification document.",
        "operationId": "getOpenApiSpec",
        "responses": {
          "200": {
            "description": "OpenAPI specification",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/internal/communities": {
      "get": {
        "summary": "List public communities",
        "description": "Returns public communities on MythOS, sorted by member count. Each community has its own llms.txt at /we/{slug}/llm.txt.",
        "operationId": "listCommunities",
        "parameters": [
          {
            "name": "slug",
            "in": "query",
            "description": "Filter by community slug (exact match)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of communities to return (1-100, default 50)",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of communities",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "communities": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CommunitySummary"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/internal/communities/{slug}/posts": {
      "get": {
        "summary": "List community posts",
        "description": "Returns approved posts in a community, sorted by score. Uses immutable post snapshots.",
        "operationId": "listCommunityPosts",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Community slug",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Search query to filter posts by title",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of posts to return (1-200, default 50)",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of approved posts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "posts": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CommunityPost"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/internal/memos/index": {
      "get": {
        "summary": "Get memo index",
        "description": "Returns a lightweight index of all memos with IDs, titles, tags, and update timestamps. No content included.",
        "operationId": "getMemoIndex",
        "responses": {
          "200": {
            "description": "Memo index",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "memos": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "tags": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "updatedAt": {
                            "type": "number"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/internal/journal": {
      "get": {
        "summary": "Read daily memo",
        "description": "Returns a daily memo for a specific date. If no memo exists for the date, returns null content.",
        "operationId": "readDailyMemo",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": true,
            "description": "Date in YYYY-MM-DD format",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          },
          {
            "name": "username",
            "in": "query",
            "description": "Username (defaults to configured default user)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Daily memo content",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "dailyMemo": {
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "string",
                          "nullable": true,
                          "description": "Format: {username}-{YYYY-MM-DD}, or null if no memo exists"
                        },
                        "date": {
                          "type": "string"
                        },
                        "content": {
                          "type": "string",
                          "nullable": true,
                          "description": "Markdown content"
                        },
                        "createdAt": {
                          "type": "number",
                          "nullable": true
                        },
                        "updatedAt": {
                          "type": "number",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid date",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "User not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Insert into daily memo section",
        "description": "Inserts a checklist task or bullet entry into a specific section of a daily memo. Auto-creates the daily memo from the user's default template if none exists for the date. Supports positional insertion via afterLine.",
        "operationId": "insertDailyMemoEntry",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": true,
            "description": "Date in YYYY-MM-DD format",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          },
          {
            "name": "username",
            "in": "query",
            "description": "Username (defaults to configured default user)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "section",
                  "entry"
                ],
                "properties": {
                  "section": {
                    "type": "string",
                    "description": "Section heading to insert into (e.g. 'Tasks', 'Timeline')"
                  },
                  "entry": {
                    "type": "string",
                    "description": "Entry text (without bullet/checkbox prefix)"
                  },
                  "entryType": {
                    "type": "string",
                    "enum": [
                      "task",
                      "bullet"
                    ],
                    "default": "bullet",
                    "description": "'task' adds '- [ ] ' prefix, 'bullet' adds '* ' prefix"
                  },
                  "afterLine": {
                    "type": "string",
                    "description": "Insert after a line matching this text exactly (trimmed). If not found, appends at end of section."
                  },
                  "sourceMarkupVersion": {
                    "type": "integer",
                    "description": "Optional. Markup version of the entry text. Omit (or 1) for legacy behavior — bare #word is auto-linked into a tag. Set to 2 to keep bare #word as literal text."
                  }
                }
              },
              "examples": {
                "addTask": {
                  "summary": "Add a checklist task",
                  "value": {
                    "section": "Tasks",
                    "entry": "Review the PR",
                    "entryType": "task"
                  }
                },
                "addTimeline": {
                  "summary": "Add a timeline entry",
                  "value": {
                    "section": "Timeline",
                    "entry": "12:30 PM — Lunch with Richard Titus"
                  }
                },
                "insertAfter": {
                  "summary": "Insert after a specific line",
                  "value": {
                    "section": "Timeline",
                    "entry": "9:45 AM — Quick sync with design team",
                    "afterLine": "* 9:00 AM — Morning standup"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Entry added successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    },
                    "section": {
                      "type": "string"
                    },
                    "entry": {
                      "type": "string",
                      "description": "The formatted entry as inserted (with prefix)"
                    },
                    "warning": {
                      "type": "string",
                      "description": "Present if afterLine was not found"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "User not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Concurrent edit conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/internal/newsletter/subscribers": {
      "post": {
        "summary": "Create a subscriber",
        "description": "Adds a subscriber to the caller's newsletter. Sets importSource=api automatically. Requires email and firstName. Optional: lastName, topics (array of owned topic slugs), frequency, digestMode.",
        "operationId": "createNewsletterSubscriber",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email",
                  "firstName"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "firstName": {
                    "type": "string"
                  },
                  "lastName": {
                    "type": "string"
                  },
                  "topics": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Topic slugs the caller owns. Omit for creator-level subscription."
                  },
                  "frequency": {
                    "type": "string",
                    "enum": [
                      "instant",
                      "daily",
                      "weekly",
                      "monthly",
                      "none"
                    ],
                    "default": "weekly"
                  },
                  "digestMode": {
                    "type": "string",
                    "enum": [
                      "bundled",
                      "separate"
                    ],
                    "default": "separate"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Subscriber created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "subscriptionId": {
                      "type": "string"
                    },
                    "pending": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Already subscribed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/internal/newsletter/subscribers/{id}": {
      "patch": {
        "summary": "Update a subscriber",
        "description": "Updates preferences for an existing subscription owned by the caller. At least one field must be provided. Topic slugs must be owned by the caller.",
        "operationId": "updateNewsletterSubscriber",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "MongoDB ObjectId of the subscription",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "firstName": {
                    "type": "string"
                  },
                  "lastName": {
                    "type": "string"
                  },
                  "topics": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Replaces existing topic preferences. Empty array resets to creator-level scope."
                  },
                  "frequency": {
                    "type": "string",
                    "enum": [
                      "instant",
                      "daily",
                      "weekly",
                      "monthly",
                      "none"
                    ]
                  },
                  "digestMode": {
                    "type": "string",
                    "enum": [
                      "bundled",
                      "separate"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Subscriber updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error or no fields to update",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Subscription not found or belongs to another creator",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/internal/memos/changes": {
      "get": {
        "summary": "Delta sync",
        "description": "Returns memos that have changed since the given timestamp. Used for incremental synchronization.",
        "operationId": "deltaSyncMemos",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "required": true,
            "description": "ISO 8601 timestamp to get changes since",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of results",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Changed memos since timestamp",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "memos": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/MemoSummary"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  }
}