{
  "openapi": "3.0.3",
  "info": {
    "title": "SocioLogic API",
    "description": "High-fidelity synthetic personas for market research. This API provides access to synthetic personas that can be interviewed, used in campaigns, and organized into focus groups.",
    "version": "1.0.0",
    "contact": {
      "name": "SocioLogic Support",
      "email": "team@sociologic.ai",
      "url": "https://sociologic.ai/docs"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://sociologic.ai/terms"
    }
  },
  "servers": [
    {
      "url": "https://sociologic.ai/api/v1",
      "description": "Production server"
    }
  ],
  "security": [
    { "ApiKeyAuth": [] },
    { "BearerAuth": [] }
  ],
  "paths": {
    "/personas": {
      "get": {
        "summary": "List personas",
        "description": "Retrieve a paginated list of available personas with optional filtering.",
        "operationId": "listPersonas",
        "tags": ["Personas"],
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "schema": { "type": "string" },
            "description": "Filter by category"
          },
          {
            "name": "tags",
            "in": "query",
            "schema": { "type": "string" },
            "description": "Comma-separated list of tags"
          },
          {
            "name": "search",
            "in": "query",
            "schema": { "type": "string" },
            "description": "Search in name, tagline, description"
          },
          {
            "name": "page",
            "in": "query",
            "schema": { "type": "integer", "default": 1 },
            "description": "Page number"
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": { "type": "integer", "default": 20, "maximum": 100 },
            "description": "Results per page"
          }
        ],
        "responses": {
          "200": {
            "description": "List of personas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Persona" }
                    },
                    "pagination": { "$ref": "#/components/schemas/Pagination" },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "summary": "Create persona",
        "description": "Generate a new private persona from a description. Costs 0.25 credits (or 1.0 with avatar).",
        "operationId": "createPersona",
        "tags": ["Personas"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["description"],
                "properties": {
                  "description": {
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 500,
                    "description": "Natural-language description of the persona to generate"
                  },
                  "include_avatar": {
                    "type": "boolean",
                    "default": false,
                    "description": "Whether to generate an AI avatar image (adds 0.75 credits)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Persona created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/Persona" },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/personas/{slug}": {
      "get": {
        "summary": "Get persona",
        "description": "Get detailed information about a specific persona by slug.",
        "operationId": "getPersona",
        "tags": ["Personas"],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "The persona's URL-friendly identifier"
          }
        ],
        "responses": {
          "200": {
            "description": "Persona details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/Persona" },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/campaigns": {
      "get": {
        "summary": "List campaigns",
        "description": "List all campaigns for the authenticated user.",
        "operationId": "listCampaigns",
        "tags": ["Campaigns"],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": { "type": "string", "enum": ["draft", "pending", "running", "completed", "failed"] },
            "description": "Filter by campaign status"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "default": 20, "maximum": 100 },
            "description": "Results per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": { "type": "integer", "default": 0 },
            "description": "Pagination offset"
          },
          {
            "name": "include_interviews",
            "in": "query",
            "schema": { "type": "boolean", "default": false },
            "description": "Include interview data"
          }
        ],
        "responses": {
          "200": {
            "description": "List of campaigns",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Campaign" }
                    },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "summary": "Create campaign",
        "description": "Create a new research campaign.",
        "operationId": "createCampaign",
        "tags": ["Campaigns"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CreateCampaignRequest" }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Campaign created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/Campaign" },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/campaigns/templates": {
      "get": {
        "summary": "List campaign templates",
        "description": "Get pre-built campaign templates with suggested questions.",
        "operationId": "listCampaignTemplates",
        "tags": ["Campaigns"],
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "schema": { "type": "string", "enum": ["product", "pricing", "ux", "brand", "marketing", "general"] },
            "description": "Filter by category"
          },
          {
            "name": "featured",
            "in": "query",
            "schema": { "type": "boolean" },
            "description": "Filter featured templates only"
          }
        ],
        "responses": {
          "200": {
            "description": "List of templates",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "templates": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/CampaignTemplate" }
                        },
                        "categories": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": { "type": "string" },
                              "name": { "type": "string" },
                              "description": { "type": "string" }
                            }
                          }
                        }
                      }
                    },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/campaigns/{id}": {
      "get": {
        "summary": "Get campaign",
        "description": "Get campaign details including personas, interviews summary, and report.",
        "operationId": "getCampaign",
        "tags": ["Campaigns"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Campaign ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Campaign details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/CampaignDetails" },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "put": {
        "summary": "Update campaign",
        "description": "Update a draft campaign. Only campaigns in draft status can be updated.",
        "operationId": "updateCampaign",
        "tags": ["Campaigns"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Campaign ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/UpdateCampaignRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Campaign updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/Campaign" },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "delete": {
        "summary": "Delete campaign",
        "description": "Delete a campaign and all associated data.",
        "operationId": "deleteCampaign",
        "tags": ["Campaigns"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Campaign ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Campaign deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": { "type": "boolean" }
                      }
                    },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/campaigns/{id}/execute": {
      "post": {
        "summary": "Execute campaign",
        "description": "Start campaign execution. This is an async operation that creates personas, conducts interviews, and generates a report.",
        "operationId": "executeCampaign",
        "tags": ["Campaigns"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Campaign ID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "existing_persona_ids": {
                    "type": "array",
                    "items": { "type": "string", "format": "uuid" },
                    "description": "Optional list of existing persona IDs to use"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Campaign execution started",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "campaign_id": { "type": "string" },
                        "status": { "type": "string" },
                        "task_id": { "type": "string" },
                        "public_access_token": { "type": "string" },
                        "estimated_personas": { "type": "integer" },
                        "estimated_interviews": { "type": "integer" },
                        "cost_breakdown": { "$ref": "#/components/schemas/CostBreakdown" }
                      }
                    },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/campaigns/{id}/export": {
      "get": {
        "summary": "Export campaign report",
        "description": "Download the campaign report as a PDF file. Campaign must be completed.",
        "operationId": "exportCampaign",
        "tags": ["Campaigns"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Campaign ID"
          }
        ],
        "responses": {
          "200": {
            "description": "PDF report",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/focus-groups": {
      "get": {
        "summary": "List focus groups",
        "description": "List all focus groups for the authenticated user.",
        "operationId": "listFocusGroups",
        "tags": ["Focus Groups"],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "default": 50, "maximum": 100 },
            "description": "Results per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": { "type": "integer", "default": 0 },
            "description": "Pagination offset"
          },
          {
            "name": "order_by",
            "in": "query",
            "schema": { "type": "string", "enum": ["created_at", "name", "persona_count"], "default": "created_at" },
            "description": "Sort field"
          },
          {
            "name": "order",
            "in": "query",
            "schema": { "type": "string", "enum": ["asc", "desc"], "default": "desc" },
            "description": "Sort direction"
          },
          {
            "name": "include_personas",
            "in": "query",
            "schema": { "type": "boolean", "default": false },
            "description": "Include full persona data"
          }
        ],
        "responses": {
          "200": {
            "description": "List of focus groups",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/FocusGroup" }
                    },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "summary": "Create focus group",
        "description": "Create a new focus group.",
        "operationId": "createFocusGroup",
        "tags": ["Focus Groups"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name"],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "Focus group name"
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Focus group description"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Focus group created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/FocusGroup" },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/focus-groups/{id}": {
      "get": {
        "summary": "Get focus group",
        "description": "Get focus group details with all its personas.",
        "operationId": "getFocusGroup",
        "tags": ["Focus Groups"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Focus group ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Focus group details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/FocusGroupWithPersonas" },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "patch": {
        "summary": "Update focus group",
        "description": "Update a focus group's name or description.",
        "operationId": "updateFocusGroup",
        "tags": ["Focus Groups"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Focus group ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "Focus group name"
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Focus group description"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Focus group updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/FocusGroup" },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "delete": {
        "summary": "Delete focus group",
        "description": "Delete a focus group. Does not delete the personas themselves.",
        "operationId": "deleteFocusGroup",
        "tags": ["Focus Groups"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Focus group ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Focus group deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": { "type": "boolean" }
                      }
                    },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/focus-groups/{id}/personas": {
      "get": {
        "summary": "List focus group personas",
        "description": "Get all personas in a focus group.",
        "operationId": "listFocusGroupPersonas",
        "tags": ["Focus Groups"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Focus group ID"
          }
        ],
        "responses": {
          "200": {
            "description": "List of personas in focus group",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Persona" }
                    },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "summary": "Add personas to focus group",
        "description": "Add one or more personas to a focus group.",
        "operationId": "addPersonasToFocusGroup",
        "tags": ["Focus Groups"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Focus group ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["persona_ids"],
                "properties": {
                  "persona_ids": {
                    "type": "array",
                    "items": { "type": "string", "format": "uuid" },
                    "minItems": 1,
                    "maxItems": 100,
                    "description": "List of persona IDs to add"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Personas added",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "added_count": { "type": "integer" },
                        "focus_group_id": { "type": "string" }
                      }
                    },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": {
            "description": "Duplicate entry - persona already in group",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Error" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "delete": {
        "summary": "Remove personas from focus group",
        "description": "Remove one or more personas from a focus group.",
        "operationId": "removePersonasFromFocusGroup",
        "tags": ["Focus Groups"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Focus group ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["persona_ids"],
                "properties": {
                  "persona_ids": {
                    "type": "array",
                    "items": { "type": "string", "format": "uuid" },
                    "minItems": 1,
                    "maxItems": 100,
                    "description": "List of persona IDs to remove"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Personas removed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "removed_count": { "type": "integer" },
                        "focus_group_id": { "type": "string" }
                      }
                    },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/personas/{slug}/memories": {
      "get": {
        "summary": "List persona memories",
        "description": "Get all memories stored for a persona. Memories are user-scoped.",
        "operationId": "listPersonaMemories",
        "tags": ["Personas"],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "The persona's URL-friendly identifier"
          }
        ],
        "responses": {
          "200": {
            "description": "List of memories",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Memory" }
                    },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "post": {
        "summary": "Create persona memory",
        "description": "Store a new memory for a persona. Memories influence future conversations.",
        "operationId": "createPersonaMemory",
        "tags": ["Personas"],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "The persona's URL-friendly identifier"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["content", "memory_type"],
                "properties": {
                  "content": { "type": "string", "maxLength": 1000 },
                  "memory_type": { "type": "string", "enum": ["fact", "preference", "experience", "opinion", "trait"] },
                  "importance_score": { "type": "number", "minimum": 0, "maximum": 1, "default": 0.5 }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Memory created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/Memory" },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "delete": {
        "summary": "Delete persona memory",
        "description": "Delete a specific memory from a persona.",
        "operationId": "deletePersonaMemory",
        "tags": ["Personas"],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "The persona's URL-friendly identifier"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["memory_id"],
                "properties": {
                  "memory_id": { "type": "string", "format": "uuid" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Memory deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "object", "properties": { "deleted": { "type": "boolean" } } },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/avatars": {
      "post": {
        "summary": "Generate avatar",
        "description": "Generate an AI avatar image for a persona or custom description.",
        "operationId": "generateAvatar",
        "tags": ["Avatars"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "persona_id": { "type": "string", "format": "uuid", "description": "Optional persona ID to generate avatar for" },
                  "style": { "type": "string", "enum": ["realistic", "illustrated"], "default": "illustrated" },
                  "name": { "type": "string", "description": "Name (if no persona_id)" },
                  "description": { "type": "string", "description": "Description (if no persona_id)" },
                  "demographics": {
                    "type": "object",
                    "properties": {
                      "age_range": { "type": "string" },
                      "gender": { "type": "string" },
                      "occupation": { "type": "string" }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Avatar generated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "avatar_url": { "type": "string", "description": "URL if uploaded to storage" },
                        "avatar_base64": { "type": "string", "description": "Base64 image data if not uploaded" },
                        "content_type": { "type": "string" },
                        "persona_id": { "type": "string" }
                      }
                    },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" }
        }
      }
    },
    "/conversations": {
      "get": {
        "summary": "List conversations",
        "description": "List all conversations for the authenticated user.",
        "operationId": "listConversations",
        "tags": ["Conversations"],
        "parameters": [
          {
            "name": "persona_id",
            "in": "query",
            "schema": { "type": "string", "format": "uuid" },
            "description": "Filter by persona ID"
          },
          {
            "name": "page",
            "in": "query",
            "schema": { "type": "integer", "default": 1 }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": { "type": "integer", "default": 10, "maximum": 50 }
          }
        ],
        "responses": {
          "200": {
            "description": "List of conversations",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Conversation" }
                    },
                    "pagination": { "$ref": "#/components/schemas/Pagination" },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      },
      "post": {
        "summary": "Create conversation",
        "description": "Create a new conversation with a persona.",
        "operationId": "createConversation",
        "tags": ["Conversations"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["persona_id"],
                "properties": {
                  "persona_id": { "type": "string", "format": "uuid" },
                  "title": { "type": "string", "maxLength": 200 }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Conversation created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/Conversation" },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/conversations/{id}": {
      "get": {
        "summary": "Get conversation",
        "description": "Get a conversation with all its messages.",
        "operationId": "getConversation",
        "tags": ["Conversations"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" }
          }
        ],
        "responses": {
          "200": {
            "description": "Conversation details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/ConversationWithMessages" },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "patch": {
        "summary": "Update conversation",
        "description": "Update conversation messages or title.",
        "operationId": "updateConversation",
        "tags": ["Conversations"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": { "type": "string", "maxLength": 200 },
                  "messages": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": { "type": "string" },
                        "role": { "type": "string", "enum": ["user", "assistant"] },
                        "content": { "type": "string" },
                        "timestamp": { "type": "string" }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Conversation updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/Conversation" },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "delete": {
        "summary": "Delete conversation",
        "description": "Delete a conversation and all its messages.",
        "operationId": "deleteConversation",
        "tags": ["Conversations"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" }
          }
        ],
        "responses": {
          "200": {
            "description": "Conversation deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "object", "properties": { "deleted": { "type": "boolean" } } },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/analytics": {
      "get": {
        "summary": "Get usage analytics",
        "description": "Get usage analytics for the authenticated user including credit usage over time and API call breakdown.",
        "operationId": "getAnalytics",
        "tags": ["Analytics"],
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "schema": { "type": "string", "enum": ["7d", "30d", "90d"], "default": "30d" },
            "description": "Time range for analytics"
          }
        ],
        "responses": {
          "200": {
            "description": "Analytics data",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "credits_over_time": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "date": { "type": "string" },
                              "credits": { "type": "integer" }
                            }
                          }
                        },
                        "api_calls_by_type": {
                          "type": "object",
                          "additionalProperties": { "type": "integer" }
                        },
                        "top_personas": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "persona_id": { "type": "string" },
                              "name": { "type": "string" },
                              "query_count": { "type": "integer" }
                            }
                          }
                        },
                        "total_credits_used": { "type": "integer" },
                        "total_api_calls": { "type": "integer" }
                      }
                    },
                    "meta": { "$ref": "#/components/schemas/ResponseMeta" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "API key starting with pl_live_ or pl_test_"
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "JWT token from Supabase Auth"
      }
    },
    "schemas": {
      "Persona": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "slug": { "type": "string" },
          "name": { "type": "string" },
          "tagline": { "type": "string" },
          "description": { "type": "string" },
          "avatar_url": { "type": "string", "nullable": true },
          "demographics": { "$ref": "#/components/schemas/Demographics" },
          "psychographics": { "$ref": "#/components/schemas/Psychographics" },
          "metadata": { "$ref": "#/components/schemas/PersonaMetadata" },
          "category": { "type": "string" },
          "tags": { "type": "array", "items": { "type": "string" } },
          "status": { "type": "string", "enum": ["active", "inactive"] },
          "is_featured": { "type": "boolean" },
          "total_queries": { "type": "integer" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "Demographics": {
        "type": "object",
        "properties": {
          "age_range": { "type": "string", "nullable": true },
          "gender": { "type": "string", "nullable": true },
          "location_country": { "type": "string", "nullable": true },
          "location_region": { "type": "string", "nullable": true },
          "occupation": { "type": "string", "nullable": true },
          "income_bracket": { "type": "string", "nullable": true },
          "education_level": { "type": "string", "nullable": true }
        }
      },
      "Psychographics": {
        "type": "object",
        "properties": {
          "interests": { "type": "array", "items": { "type": "string" } },
          "values": { "type": "array", "items": { "type": "string" } },
          "pain_points": { "type": "array", "items": { "type": "string" } },
          "goals": { "type": "array", "items": { "type": "string" } },
          "communication_style": { "type": "string" }
        }
      },
      "PersonaMetadata": {
        "type": "object",
        "properties": {
          "fidelity_score": { "type": "number", "minimum": 0, "maximum": 1 },
          "response_temperature": { "type": "number" },
          "model_version": { "type": "string" }
        }
      },
      "Campaign": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "name": { "type": "string" },
          "description": { "type": "string", "nullable": true },
          "status": { "type": "string", "enum": ["draft", "pending", "running", "completed", "failed"] },
          "persona_count": { "type": "integer" },
          "questions": { "type": "array", "items": { "$ref": "#/components/schemas/CampaignQuestion" } },
          "interviews_completed": { "type": "integer" },
          "progress_percent": { "type": "number" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "CampaignDetails": {
        "allOf": [
          { "$ref": "#/components/schemas/Campaign" },
          {
            "type": "object",
            "properties": {
              "personas": { "type": "array", "items": { "$ref": "#/components/schemas/Persona" } },
              "interviews_summary": { "type": "object" },
              "report": { "type": "object", "nullable": true },
              "cost_breakdown": { "$ref": "#/components/schemas/CostBreakdown" }
            }
          }
        ]
      },
      "CampaignQuestion": {
        "type": "object",
        "required": ["id", "text"],
        "properties": {
          "id": { "type": "string" },
          "text": { "type": "string", "minLength": 1, "maxLength": 500 },
          "type": { "type": "string", "enum": ["open", "scale", "multiple_choice"], "default": "open" },
          "required": { "type": "boolean", "default": true },
          "options": { "type": "array", "items": { "type": "string" } }
        }
      },
      "CampaignTemplate": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "name": { "type": "string" },
          "description": { "type": "string" },
          "category": { "type": "string" },
          "questions": { "type": "array", "items": { "$ref": "#/components/schemas/CampaignQuestion" } },
          "suggested_persona_count": { "type": "integer" },
          "is_featured": { "type": "boolean" },
          "usage_count": { "type": "integer" },
          "estimated_cost": { "$ref": "#/components/schemas/CostBreakdown" }
        }
      },
      "CreateCampaignRequest": {
        "type": "object",
        "required": ["name", "questions"],
        "properties": {
          "name": { "type": "string", "minLength": 1, "maxLength": 200 },
          "description": { "type": "string", "maxLength": 2000 },
          "template_id": { "type": "string", "format": "uuid" },
          "questions": { "type": "array", "items": { "$ref": "#/components/schemas/CampaignQuestion" }, "minItems": 1, "maxItems": 20 },
          "persona_brief": { "type": "string", "minLength": 10, "maxLength": 1000 },
          "persona_count": { "type": "integer", "minimum": 1, "maximum": 100, "default": 10 },
          "existing_persona_ids": { "type": "array", "items": { "type": "string", "format": "uuid" } },
          "focus_group_ids": { "type": "array", "items": { "type": "string", "format": "uuid" } },
          "create_focus_group": { "type": "boolean", "default": false },
          "focus_group_name": { "type": "string", "maxLength": 200 }
        }
      },
      "UpdateCampaignRequest": {
        "type": "object",
        "properties": {
          "name": { "type": "string", "minLength": 1, "maxLength": 200 },
          "description": { "type": "string", "maxLength": 2000, "nullable": true },
          "questions": { "type": "array", "items": { "$ref": "#/components/schemas/CampaignQuestion" }, "minItems": 1, "maxItems": 20 },
          "persona_brief": { "type": "string", "minLength": 10, "maxLength": 1000, "nullable": true },
          "persona_count": { "type": "integer", "minimum": 1, "maximum": 100 }
        }
      },
      "CostBreakdown": {
        "type": "object",
        "properties": {
          "personaCreation": { "type": "integer" },
          "interviews": { "type": "integer" },
          "report": { "type": "integer" },
          "totalCost": { "type": "integer" }
        }
      },
      "FocusGroup": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "name": { "type": "string" },
          "description": { "type": "string", "nullable": true },
          "persona_count": { "type": "integer" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "FocusGroupWithPersonas": {
        "allOf": [
          { "$ref": "#/components/schemas/FocusGroup" },
          {
            "type": "object",
            "properties": {
              "personas": { "type": "array", "items": { "$ref": "#/components/schemas/Persona" } }
            }
          }
        ]
      },
      "Memory": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "persona_id": { "type": "string", "format": "uuid" },
          "user_id": { "type": "string", "format": "uuid" },
          "content": { "type": "string" },
          "memory_type": { "type": "string", "enum": ["fact", "preference", "experience", "opinion", "trait"] },
          "importance_score": { "type": "number", "minimum": 0, "maximum": 1 },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "Conversation": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "profile_id": { "type": "string", "format": "uuid" },
          "persona_id": { "type": "string", "format": "uuid" },
          "title": { "type": "string", "nullable": true },
          "last_message_preview": { "type": "string", "nullable": true },
          "message_count": { "type": "integer" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "ConversationWithMessages": {
        "allOf": [
          { "$ref": "#/components/schemas/Conversation" },
          {
            "type": "object",
            "properties": {
              "messages": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": { "type": "string" },
                    "role": { "type": "string", "enum": ["user", "assistant"] },
                    "content": { "type": "string" },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                }
              },
              "persona": { "$ref": "#/components/schemas/Persona" }
            }
          }
        ]
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "total": { "type": "integer" },
          "page": { "type": "integer" },
          "per_page": { "type": "integer" },
          "total_pages": { "type": "integer" }
        }
      },
      "ResponseMeta": {
        "type": "object",
        "properties": {
          "request_id": { "type": "string" },
          "api_version": { "type": "string" },
          "credits_used": { "type": "integer" },
          "credits_remaining": { "type": "integer" },
          "response_time_ms": { "type": "integer" }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "string" },
              "message": { "type": "string" },
              "details": { "type": "object" }
            }
          },
          "meta": { "$ref": "#/components/schemas/ResponseMeta" }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid request parameters or body",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid authentication",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      },
      "PaymentRequired": {
        "description": "Insufficient credits",
        "headers": {
          "X-Credits-Required": { "schema": { "type": "integer" } },
          "X-Credits-Available": { "schema": { "type": "integer" } },
          "X-Payment-Required-URL": { "schema": { "type": "string" } }
        },
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded",
        "headers": {
          "X-RateLimit-Limit": { "schema": { "type": "integer" } },
          "X-RateLimit-Remaining": { "schema": { "type": "integer" } },
          "X-RateLimit-Reset": { "schema": { "type": "integer" } },
          "Retry-After": { "schema": { "type": "integer" } }
        },
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Personas",
      "description": "Synthetic personas for market research"
    },
    {
      "name": "Campaigns",
      "description": "Research campaigns with personas, interviews, and reports"
    },
    {
      "name": "Avatars",
      "description": "AI-generated avatar images for personas"
    },
    {
      "name": "Conversations",
      "description": "Saved conversation history with personas"
    },
    {
      "name": "Analytics",
      "description": "Usage analytics and credit tracking"
    },
    {
      "name": "Focus Groups",
      "description": "Collections of personas for reuse across campaigns"
    }
  ]
}
