{"openapi":"3.1.0","info":{"title":"Minds Public API","version":"v1","description":"OpenAPI 3.1.0 spec for the Minds public API (https://getminds.ai/api/v1 / https://api.getminds.ai/v1). Generate a typed TypeScript client by running an OpenAPI generator (e.g. `openapi-typescript`) against `/_openapi.json`. Auth: send `Authorization: Bearer minds_…_key`; create keys in Settings → API Keys."},"servers":[{"url":"https://api.getminds.ai","description":"Production (api subdomain)"},{"url":"https://getminds.ai","description":"Production (apex)"}],"paths":{"/api/v1/groups/allocation-preview":{"post":{"parameters":[],"responses":{"200":{"description":"Deterministic allocation preview."},"400":{"description":"Invalid count or distributions."},"401":{"description":"Missing or invalid API key."}},"operationId":"previewCohortAllocation","summary":"Preview deterministic cohort allocation","description":"Convert marginal distributions into exact integer quotas and deterministic member profiles without creating a Group. This is the contract intended for API clients and future product UI controls.","tags":["Groups"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["memberCount","distributions"],"properties":{"memberCount":{"type":"integer","minimum":1,"maximum":1000},"seedBasis":{"type":"string","maxLength":1000},"distributions":{"type":"array","maxItems":25,"items":{"$ref":"#/components/schemas/GroundingDistribution"}},"cohortAllocation":{"type":"object"}}}}}}}},"/api/v1/groups/from-brief":{"post":{"parameters":[],"responses":{"201":{"description":"Grounded group created.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/GroupFromBriefResult"}}}}}},"400":{"description":"Missing `text`, text too long, or invalid input."},"401":{"description":"Missing or invalid API key."},"403":{"description":"Plan limit reached (`code: PLAN_LIMIT`)."},"422":{"description":"No personas could be derived from the brief."},"500":{"description":"Internal server error."}},"operationId":"createGroupFromBrief","summary":"Create a grounded group from a brief","description":"Create one spark group from a free-text audience brief. The server gathers optional attachment/link/keyword context, researches real-world grounding data when available, generates personas, creates the sparks, and returns the new group plus optional grounding metadata.","tags":["Groups"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string","minLength":1,"maxLength":200000,"description":"Free-text brief describing the audience or population to represent."},"name":{"type":"string","description":"Optional group name override. When omitted, the server names the group from the brief or detected personas."},"files":{"type":"array","description":"Already-uploaded file attachments to include as context.","items":{"type":"object","required":["name","url"],"properties":{"name":{"type":"string"},"url":{"type":"string"}}}},"links":{"type":"array","description":"URLs to scrape for additional context.","items":{"type":"string"}},"keywords":{"type":"array","description":"Search keywords used as extra context and research seeds.","items":{"type":"string"}},"isLinkSharingEnabled":{"type":"boolean","description":"Enable public link sharing for the created group."},"groupCreationMode":{"type":"string","enum":["balanced","segment_coverage","benchmark_depth"],"default":"balanced","description":"Group creation mode. `balanced` (default) keeps the group compact and plan-aware; `segment_coverage` broadens coverage within the plan cap; `benchmark_depth` uses the full paid group allowance for maximum representative depth (200 Minds on standard Team, up to the 1,000-Mind hard ceiling with a custom allowance). The deeper modes require a Team plan — other plans are silently downgraded to `balanced`. The response echoes the effective mode."},"datasetSegmentation":{"type":"object","description":"Reviewed variable distributions returned by the segmentation-preview endpoint. Requires Team plus `benchmark_depth`. Selected variables shape a representative cohort; observed joint combinations remain audit evidence and are not converted one-for-one into Minds."},"cohortAllocation":{"type":"object","description":"Deterministic allocation controls. Grounded marginals are converted into exact integer quotas server-side; the LLM does not decide proportions. Omit for deterministic defaults.","properties":{"enabled":{"type":"boolean","default":true},"seed":{"type":"string","maxLength":200},"distributionNames":{"type":"array","maxItems":200,"items":{"type":"string"}},"maxDistributions":{"type":"integer","minimum":1,"maximum":200,"default":200},"minSegmentCount":{"type":"integer","minimum":0,"maximum":20,"default":0},"targetOverrides":{"type":"array","maxItems":200,"description":"Partial or full target-percentage overrides. Unspecified segments keep their source percentages; the audit preserves sourcePct and normalizedTargetPct separately.","items":{"type":"object","required":["distribution","segments"],"properties":{"distribution":{"type":"string"},"segments":{"type":"array","items":{"type":"object","required":["label","pct"],"properties":{"label":{"type":"string"},"pct":{"type":"number","minimum":0,"maximum":100}}}}}}},"jointStrategy":{"type":"string","enum":["independent","aligned"],"default":"independent"},"includeProfilesInResponse":{"type":"boolean","default":false},"appendProfileToDescription":{"type":"boolean","default":true}}}}},"examples":{"demographicAudience":{"summary":"Create an audience group","value":{"text":"Berlin Spati customers who buy late-night snacks","name":"Berlin Spati Customers","links":["https://example.com/customer-research"],"keywords":["Berlin convenience store demographics"]}}}}}}}},"/api/v1/groups/from-brief/segmentation-preview":{"post":{"parameters":[],"responses":{"200":{"description":"Complete variable distribution review."},"400":{"description":"Unsupported, empty, or invalid spreadsheet."},"401":{"description":"Missing or invalid authentication."},"403":{"description":"Enterprise dataset segmentation review requires Team."},"413":{"description":"Dataset exceeds the explicit review limit; no partial preview is returned."}},"operationId":"previewGroupDatasetSegmentation","summary":"Preview spreadsheet segmentation distributions","description":"Enterprise review step for grounded group creation. Parses one XLSX or CSV structurally, excludes likely respondent identifiers by default, and returns every variable distribution. Joint profiles are counted for audit only; rows are never silently sampled.","tags":["Groups"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"object","required":["name","url"],"properties":{"name":{"type":"string"},"url":{"type":"string"}}},"segmentationColumns":{"type":"array","items":{"type":"string"},"description":"Column keys returned by an earlier preview. Omit to select every non-identifier column."}}}}}}}},"/api/v1/panels/{panelId}":{"delete":{"parameters":[{"in":"path","name":"panelId","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Panel deleted."},"400":{"description":"Invalid panel ID or the Flow is not a panel."},"401":{"description":"Missing or invalid authentication."},"403":{"description":"Only the panel owner may delete it."},"404":{"description":"Panel not found."}},"operationId":"deletePanel","summary":"Delete a panel","description":"Delete a panel-mode Flow owned by the authenticated user.","tags":["Panels"],"security":[{"ApiKeyAuth":[]}]},"get":{"parameters":[{"in":"path","name":"panelId","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Panel details.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PanelDetail"}}}}}},"400":{"description":"Invalid panel ID or the Flow is not a panel."},"401":{"description":"Missing or invalid authentication."},"403":{"description":"The caller cannot access this panel."},"404":{"description":"Panel not found."}},"operationId":"getPanel","summary":"Get a panel","description":"Return a panel-mode Flow with its attached groups, Minds, and messages.","tags":["Panels"],"security":[{"ApiKeyAuth":[]}]}},"/api/v1/panels/{panelId}/ask":{"post":{"parameters":[{"in":"path","name":"panelId","required":true,"description":"Panel UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"SSE stream of panel generation events, or a durable queue receipt when responseMode is queued.","content":{"text/event-stream":{"schema":{"type":"string","description":"Server-Sent Events stream. Each `data:` payload is a JSON object matching `PanelAskSseEvent`."},"examples":{"result":{"summary":"Final result event","value":"data: {\"type\":\"result\",\"outputData\":{\"title\":\"Rate this 1-5\",\"type\":\"scale\",\"groups\":[]},\"outputType\":\"bar\"}\\n\\n"}}},"application/json":{"schema":{"type":"object","required":["status","count","questionGroupId","clientRequestId","queuedMessage"],"properties":{"status":{"type":"string","enum":["queued"]},"jobId":{"type":"string"},"count":{"type":"integer","minimum":1},"questionGroupId":{"type":"string"},"clientRequestId":{"type":"string","format":"uuid"},"queuedMessage":{"type":"boolean","enum":[true]}}}}},"x-event-schema":{"$ref":"#/components/schemas/PanelAskSseEvent"}},"400":{"description":"Missing question, invalid panel ID, invalid model override, no attached groups, or no minds in selected groups."},"401":{"description":"Missing or invalid API key."},"403":{"description":"Caller cannot access the panel, or plan message limit reached (`code: PLAN_LIMIT`)."},"404":{"description":"Panel does not exist."},"500":{"description":"Internal server error."}},"operationId":"askPanel","summary":"Ask a panel question","description":"Send a question to all minds in a panel or a selected subset of attached groups. Returns a Server-Sent Events stream with start, optional classification, per-mind answers, aggregation progress, final output data, and done events.","tags":["Panels"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PanelAskRequest"},"examples":{"basic":{"summary":"Ask all groups","value":{"question":"On a scale of 1-10, how likely are you to recommend this product?"}},"withContext":{"summary":"Ask selected groups with context","value":{"question":"What should we improve in this onboarding flow?","groupIds":["550e8400-e29b-41d4-a716-446655440000"],"attachments":[{"url":"https://example.com/onboarding.pdf","name":"Onboarding flow","type":"application/pdf"}],"links":[{"label":"https://competitor.example.com/onboarding","id":"competitor-onboarding"}]}}}}}}}},"/api/v1/panels/{panelId}/export-download":{"get":{"parameters":[{"in":"path","name":"panelId","required":true,"description":"Panel UUID.","schema":{"type":"string","format":"uuid"}},{"in":"query","name":"jobId","required":false,"description":"Completed export job ID. Optional when the panel already has a persisted export.","schema":{"type":"string"}}],"responses":{"200":{"description":"PDF export file.","headers":{"Content-Disposition":{"description":"Attachment filename for the PDF.","schema":{"type":"string"}}},"content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Job is not completed, or the target flow is not a panel."},"401":{"description":"Missing or invalid API key."},"403":{"description":"Caller cannot access the panel."},"404":{"description":"Panel, export job, or generated file does not exist."},"500":{"description":"Storage not configured, download failed, or internal server error."}},"operationId":"downloadPanelExport","summary":"Download a panel PDF export","description":"Download the latest persisted PDF export for a panel, or a completed PDF export job when `jobId` is provided.","tags":["Panels"],"security":[{"ApiKeyAuth":[]}]}},"/api/v1/panels/{panelId}/export-status":{"get":{"parameters":[{"in":"path","name":"panelId","required":true,"description":"Panel UUID.","schema":{"type":"string","format":"uuid"}},{"in":"query","name":"jobId","required":false,"description":"Specific export job ID. Omit to return the latest persisted export when available.","schema":{"type":"string"}},{"in":"query","name":"kind","required":false,"description":"Export kind for job-specific polling. Used to avoid falling back to a different PDF kind.","schema":{"type":"string","enum":["executive_brief","full_report"]}}],"responses":{"200":{"description":"Export status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PanelExportStatusResponse"}}}},"400":{"description":"Invalid panel ID or unsupported panel flow."},"401":{"description":"Missing or invalid API key."},"403":{"description":"Caller cannot access the panel."},"404":{"description":"Panel, export job, or completed export does not exist."},"500":{"description":"Internal server error."}},"operationId":"getPanelExportStatus","summary":"Get panel export status","description":"Check the status of a queued PDF export job. If `jobId` is omitted and the panel has a persisted export, returns that completed export immediately.","tags":["Panels"],"security":[{"ApiKeyAuth":[]}]}},"/api/v1/panels/{panelId}/export":{"post":{"parameters":[{"in":"path","name":"panelId","required":true,"description":"Panel UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Export created or queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PanelExportResponse"}}}},"400":{"description":"Invalid panel ID, unsupported panel flow, or invalid export format."},"401":{"description":"Missing or invalid API key."},"403":{"description":"Caller cannot access the panel."},"404":{"description":"Panel does not exist."},"500":{"description":"Internal server error."}},"operationId":"exportPanel","summary":"Export panel results","description":"Export all answered panel questions. Executive-summary and full-report PDF exports enqueue asynchronous jobs and return a job ID that can be polled with `getPanelExportStatus`. Markdown, DOCX, PPTX, CSV and XLS exports return a downloadable artifact immediately.","tags":["Panels"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PanelExportRequest"},"examples":{"executiveBriefPdf":{"summary":"Executive summary PDF export","value":{"kind":"executive_brief","format":"pdf"}},"fullReportPdf":{"summary":"Queued full report PDF export","value":{"kind":"full_report","format":"pdf"}},"rawDataCsv":{"summary":"Raw answers CSV export","value":{"kind":"raw_data","format":"csv"}}}}}}}},"/api/v1/panels/{panelId}/research-plans/preview":{"post":{"parameters":[{"in":"path","name":"panelId","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Saved plan draft and confirmation questions.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object"}}}}}},"400":{"description":"Invalid request."},"401":{"description":"Unauthorized."},"403":{"description":"Panel access denied."},"404":{"description":"Panel or draft not found."},"409":{"description":"Draft revision conflict."}},"operationId":"previewPanelResearchPlan","summary":"Preview or revise a panel research plan","description":"Let the research-planning model capture intent, main source, questions, optional methods, semantic outputs, missing inputs, and confirmation questions. The versioned draft is saved but never executed by this endpoint.","tags":["Panels","Research"],"security":[{"ApiKeyAuth":[]}]}},"/api/v1/panels/{panelId}/studies/{studyId}":{"get":{"parameters":[{"in":"path","name":"panelId","required":true,"schema":{"type":"string","format":"uuid"}},{"in":"path","name":"studyId","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Durable study status.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object"}}}}}},"401":{"description":"Unauthorized."},"403":{"description":"Panel access denied."},"404":{"description":"Study not found."}},"operationId":"getPanelResearchStudy","summary":"Get research study status","description":"Return durable progress, the immutable confirmed plan snapshot, questionnaire answers/artifacts, and stage readiness for a confirmed panel study.","tags":["Panels","Research"],"security":[{"ApiKeyAuth":[]}]}},"/api/v1/panels/{panelId}/studies":{"post":{"parameters":[{"in":"path","name":"panelId","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Study queued.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object"}}}}}},"400":{"description":"Plan is incomplete, unconfirmed, invalid, unavailable, or not executable."},"401":{"description":"Unauthorized."},"403":{"description":"Panel or draft access denied."},"404":{"description":"Panel or draft not found."},"409":{"description":"Draft already confirmed for another study."}},"operationId":"runPanelResearchStudy","summary":"Confirm and run a panel research study","description":"Execute an exact saved research-plan revision after explicit confirmation. The server, not the client or model, marks required capabilities reviewed and enforces advanced-method opt-in and method availability.","tags":["Panels","Research"],"security":[{"ApiKeyAuth":[]}]}},"/api/v1/panels/{panelId}/summary":{"get":{"parameters":[{"in":"path","name":"panelId","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Persisted semantic summary.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object"}}}}}},"400":{"description":"Flow is not a panel."},"401":{"description":"Unauthorized."},"403":{"description":"Panel access denied."},"404":{"description":"Panel not found."}},"operationId":"getPanelSemanticSummary","summary":"Get a panel semantic summary","description":"Return the persisted whole-study summary, semantic output blocks, staleness, and message coverage. Renderers are hints; consumers may introduce new UI logic without changing evidence contracts.","tags":["Panels","Research"],"security":[{"ApiKeyAuth":[]}]},"post":{"parameters":[{"in":"path","name":"panelId","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Generated semantic summary.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object"}}}}}},"400":{"description":"Flow is not a panel or does not have enough content."},"401":{"description":"Unauthorized."},"403":{"description":"Panel access denied."},"404":{"description":"Panel not found."}},"operationId":"refreshPanelSemanticSummary","summary":"Generate or refresh a panel semantic summary","description":"Generate and persist a whole-study summary with flexible semantic blocks. Visual-source evidence is represented as heatmaps rather than generic distribution charts.","tags":["Panels","Research"],"security":[{"ApiKeyAuth":[]}]}},"/api/v1/panels":{"get":{"parameters":[{"in":"query","name":"limit","required":false,"description":"Max panels per page.","schema":{"type":"integer","minimum":1,"maximum":100,"default":100}},{"in":"query","name":"offset","required":false,"description":"Number of panels to skip.","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"A page of panels.","content":{"application/json":{"schema":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PanelSummary"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"401":{"description":"Missing or invalid API key."},"500":{"description":"Internal server error."}},"operationId":"listPanels","summary":"List panels","description":"List panel-mode flows (multi-spark panel chats) owned by the authenticated user. Each panel embeds its attached groups and their member sparks.","tags":["Panels"],"security":[{"ApiKeyAuth":[]}]},"post":{"parameters":[],"responses":{"201":{"description":"Panel created.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PanelCreated"}}}}}},"400":{"description":"Missing `name`."},"401":{"description":"Missing or invalid API key."},"403":{"description":"Plan limit reached (`code: PLAN_LIMIT`)."},"404":{"description":"One or more `groupIds` not found or not accessible to the caller."},"500":{"description":"Internal server error."}},"operationId":"createPanel","summary":"Create a panel","description":"Create a new panel-mode flow. Optionally attach one or more existing spark groups (the caller must have access to each — owner, member, team-shared, or public).","tags":["Panels"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Panel name."},"groupIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"IDs of spark groups to attach. De-duplicated server-side."},"isLinkSharingEnabled":{"type":"boolean","description":"Enable public link sharing for the panel and its attached groups/Minds."}}}}}}}},"/api/v1/research-methods":{"get":{"parameters":[],"responses":{"200":{"description":"Versioned research methods.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Missing or invalid authentication."}},"operationId":"listResearchMethods","summary":"List research methods","description":"Return the versioned research-method catalog, explicit executable state, availability, configuration JSON Schemas, semantic output types, and fallback methods. Experimental and planned methods are visible for framework compatibility but cannot be executed.","tags":["Research"],"security":[{"ApiKeyAuth":[]}]}},"/api/v1/sparks/{sparkId}":{"get":{"parameters":[{"in":"path","name":"sparkId","required":true,"description":"Spark UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Spark detail.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/SparkDetail"}}}}}},"400":{"description":"Invalid spark ID format (not a UUID)."},"401":{"description":"Missing or invalid API key."},"403":{"description":"Caller does not have access to this spark."},"404":{"description":"Spark does not exist."},"500":{"description":"Internal server error."}},"operationId":"getSpark","summary":"Get a spark by ID","description":"Retrieve full details for a single spark, including its generated system prompt, sharing settings, voice clone status, and knowledge-item count. Returns 403 if the caller is not the owner, team member, direct member, or the spark is not public.","tags":["Sparks"],"security":[{"ApiKeyAuth":[]}]}},"/api/v1/sparks/{sparkId}/export":{"post":{"parameters":[{"in":"path","name":"sparkId","required":true,"description":"Spark UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Cached artifact or queued job."},"400":{"description":"Invalid spark ID or export format."},"401":{"description":"Authentication required for a private Mind."},"403":{"description":"Caller cannot access the Mind."},"404":{"description":"Mind does not exist."},"500":{"description":"Internal server error."}},"operationId":"exportSparkPersona","summary":"Export a Mind persona profile","description":"Generate a branded persona profile for a single Mind (Spark) summarizing who they are, how they think and what they read. The heavy generation runs in the processor; the endpoint returns the artifact inline (`content` for md, `contentBase64` for pdf/docx/pptx) and serves a cached result instantly. Formats: pdf (landscape), md, docx, pptx.","tags":["Sparks"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"format":{"type":"string","enum":["pdf","md","docx","pptx"],"default":"md"},"force":{"type":"boolean","default":false,"description":"Regenerate even when a cached artifact exists."}}}}}}}},"/api/v1/sparks/{sparkId}/retrain":{"post":{"parameters":[{"in":"path","name":"sparkId","required":true,"description":"Spark UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Retrain queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrainingStatus"}}}},"400":{"description":"Invalid spark ID format (not a UUID)."},"401":{"description":"Missing or invalid API key."},"403":{"description":"Caller does not own this spark."},"404":{"description":"Spark does not exist."},"409":{"description":"Mind is still queued or running — a retrain is already in flight."},"500":{"description":"Internal server error."}},"operationId":"retrainSpark","summary":"Retrain a mind","description":"Re-run training for a mind that has finished (status `completed` or `failed`). Atomically claims the mind back to `queued` and re-enqueues the auto-spark worker. Returns 409 if the mind is still `queued` or `running` (a retrain is already in flight). The response is the fresh training block — poll GET /v1/sparks/{id}/training until `readyToChat` is true.","tags":["Sparks"],"security":[{"ApiKeyAuth":[]}]}},"/api/v1/sparks/{sparkId}/training":{"get":{"parameters":[{"in":"path","name":"sparkId","required":true,"description":"Spark UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Training status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrainingStatus"}}}},"400":{"description":"Invalid spark ID format (not a UUID)."},"401":{"description":"Missing or invalid API key."},"403":{"description":"Caller does not have access to this spark."},"404":{"description":"Spark does not exist."},"500":{"description":"Internal server error."}},"operationId":"getSparkTrainingStatus","summary":"Poll a mind's training status","description":"Returns the live training lifecycle for a mind. A mind's `id` exists the instant it is created, but it is only usable once `readyToChat` is `true`. Poll this endpoint after creating a mind in an auto mode (`keywords`, `clone`, `link`) until `readyToChat` flips true. `manual`-mode minds are `completed` immediately. Statuses are `queued`, `running`, `completed`, `failed` (there is no `idle`). On `failed`, `error.retryable` indicates whether `POST /v1/sparks/{id}/retrain` is worth calling.","tags":["Sparks"],"security":[{"ApiKeyAuth":[]}]}},"/api/v1/sparks":{"get":{"parameters":[{"in":"query","name":"search","description":"Case-insensitive substring match against name, description, and discipline.","required":false,"schema":{"type":"string"}},{"in":"query","name":"limit","description":"Max sparks per page.","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":100}},{"in":"query","name":"offset","description":"Number of sparks to skip.","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"A page of sparks.","content":{"application/json":{"schema":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SparkSummary"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"400":{"description":"Invalid `limit` or `offset`."},"401":{"description":"Missing or invalid API key."},"500":{"description":"Internal server error."}},"operationId":"listSparks","summary":"List sparks (minds)","description":"List all sparks (AI minds) owned by the authenticated user. Supports text search by name/description/discipline and offset-based pagination. Ephemeral sparks (created during in-product chats) are excluded.","tags":["Sparks"],"security":[{"ApiKeyAuth":[]}]},"post":{"parameters":[],"responses":{"201":{"description":"Spark created. The `training` block carries the initial lifecycle state: `queued` for auto modes, `completed` for `manual`.","content":{"application/json":{"schema":{"type":"object","required":["data","training"],"properties":{"data":{"$ref":"#/components/schemas/SparkSummary"},"training":{"$ref":"#/components/schemas/TrainingStatus"}}}}}},"400":{"description":"Validation error (missing `name`/`discipline`, invalid mode, mode-specific field missing, etc.)."},"401":{"description":"Missing or invalid API key."},"403":{"description":"Plan limit reached (`code: PLAN_LIMIT`)."},"500":{"description":"Internal server error."}},"operationId":"createSpark","summary":"Create a spark (mind)","description":"Create a new AI mind. Choose a training `mode`: `keywords` (default) seeds from keyword topics, `clone` emulates a named person/profile, `link` scrapes a URL, `manual` skips automatic data collection. The returned `training` block reflects the mind's lifecycle: auto-processing modes start `queued` (poll `GET /v1/sparks/{id}/training` until `readyToChat` is true), while `manual` minds are `completed` immediately. A mind's `id` exists before it is ready — do not chat until `readyToChat` is true.","tags":["Sparks"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSparkRequest"},"examples":{"keywords":{"summary":"Train from keywords","value":{"name":"Marketing Expert","description":"B2B SaaS marketing director","mode":"keywords","type":"expert","discipline":"Marketing","keywords":["B2B marketing","SaaS","growth marketing"],"tags":["marketing","b2b"]}},"clone":{"summary":"Clone a persona","value":{"name":"Ada Lovelace AI","description":"AI trained to emulate Ada Lovelace","mode":"clone","type":"expert","discipline":"Computer Science","personaContext":"Ada Lovelace, pioneering computer scientist"}},"link":{"summary":"Train from URL","value":{"name":"Brand Voice Expert","mode":"link","type":"creative","discipline":"Brand Strategy","contextLink":"https://example.com/brand-guidelines"}}}}}}}}},"components":{"schemas":{"GroupFromBriefResult":{"type":"object","required":["id","name","sparkCount","sparks","createdAt","updatedAt","isPublic","isSharedWithTeam","isLinkSharingEnabled","currentMemberRole","grounding","groupCreationMode"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"sparkCount":{"type":"integer"},"sparks":{"type":"array","items":{"$ref":"#/components/schemas/GroupSparkSummary"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"isPublic":{"type":"boolean"},"isSharedWithTeam":{"type":"boolean"},"isLinkSharingEnabled":{"type":"boolean"},"publicShareId":{"type":["string","null"]},"currentMemberRole":{"type":"string","enum":["owner"]},"grounding":{"oneOf":[{"$ref":"#/components/schemas/GroupGrounding"},{"type":"null"}]},"groupCreationMode":{"type":"string","enum":["balanced","segment_coverage","benchmark_depth"],"description":"The EFFECTIVE creation mode applied by the server (after the plan gate — may differ from the requested mode on non-Team plans)."},"datasetSegmentation":{"oneOf":[{"type":"object","properties":{"selectedVariableCount":{"type":"integer"},"observedProfileCount":{"type":"integer"},"recommendedMindCount":{"type":"integer"},"createdMindCount":{"type":"integer"}}},{"type":"null"}]},"cohortAllocation":{"oneOf":[{"type":"object","required":["config","audit"],"properties":{"config":{"type":"object"},"audit":{"type":"object"},"profiles":{"type":"array","items":{"type":"object"}}}},{"type":"null"}]}}},"GroupSparkSummary":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"discipline":{"type":["string","null"]},"profileImageUrl":{"type":["string","null"]}}},"GroupGrounding":{"type":"object","required":["distributions","sources","summary","confidence"],"properties":{"distributions":{"type":"array","items":{"$ref":"#/components/schemas/GroundingDistribution"}},"sources":{"type":"array","items":{"$ref":"#/components/schemas/GroundingSource"}},"summary":{"type":"string"},"confidence":{"type":"number","minimum":0,"maximum":1},"suggestedMinGroupSize":{"type":"integer","minimum":3,"maximum":50}}},"GroundingDistribution":{"type":"object","required":["name","distribution"],"properties":{"name":{"type":"string"},"distribution":{"type":"array","items":{"type":"object","required":["label","pct","sourceIdx"],"properties":{"label":{"type":"string"},"pct":{"type":"number","minimum":0,"maximum":100},"sourceIdx":{"type":"integer","minimum":0}}}},"tier":{"type":"string","enum":["target","broader","general","global"]}}},"GroundingSource":{"type":"object","required":["url","title","snippet","domain","confidence"],"properties":{"url":{"type":"string"},"title":{"type":"string"},"snippet":{"type":"string"},"domain":{"type":"string"},"publishedDate":{"type":"string"},"confidence":{"type":"number","minimum":0,"maximum":1},"tier":{"type":"string","enum":["target","broader","general","global"]},"isUserProvided":{"type":"boolean"}}},"PanelAskRequest":{"type":"object","required":["question"],"properties":{"question":{"type":"string","minLength":1,"description":"Research question to ask the panel."},"groupIds":{"type":"array","description":"Optional subset of attached group UUIDs to ask. Defaults to all groups on the panel.","items":{"type":"string","format":"uuid"}},"attachments":{"type":"array","description":"Files or images to process once and include as context for every panelist.","items":{"$ref":"#/components/schemas/PanelAttachment"}},"links":{"type":"array","description":"Web links to fetch and summarize for context.","items":{"$ref":"#/components/schemas/PanelContextLink"}},"keywords":{"type":"array","description":"Keyword/source pairs to fetch and summarize for context.","items":{"$ref":"#/components/schemas/PanelKeywordContext"}},"model":{"type":"string","description":"Optional per-request model override. Must be sent together with `provider`."},"provider":{"type":"string","enum":["openai","anthropic","google"],"description":"Provider for the model override. Must be sent together with `model`."},"disableDiversityCheck":{"type":"boolean","default":false,"description":"Skip the diversity-enforced regeneration loop for benchmark or ablation runs."},"disableQuestionClassifier":{"type":"boolean","default":false,"description":"Skip automatic scale/categorical/qualitative classification."},"responseMode":{"type":"string","enum":["stream","queued"],"default":"stream","description":"Use queued to persist the question and return immediately while durable workers generate the answers."},"clientRequestId":{"type":"string","format":"uuid","description":"Optional idempotency key for queued submissions."}}},"PanelAttachment":{"type":"object","properties":{"url":{"type":"string","description":"External URL for the uploaded or remote file."},"path":{"type":"string","description":"Storage path for an uploaded file."},"name":{"type":"string"},"type":{"type":"string","description":"MIME type when known."}}},"PanelContextLink":{"type":"object","properties":{"label":{"type":"string","description":"URL or display label."},"url":{"type":"string","description":"URL to fetch when separate from `label`."},"id":{"type":"string"}}},"PanelKeywordContext":{"type":"object","properties":{"label":{"type":"string","description":"Keyword or topic label."},"url":{"type":"string","description":"Optional source URL for the keyword."},"id":{"type":"string"}}},"PanelAskSseEvent":{"oneOf":[{"$ref":"#/components/schemas/PanelAskStartEvent"},{"$ref":"#/components/schemas/PanelAskClassificationEvent"},{"$ref":"#/components/schemas/PanelAskAnswerEvent"},{"$ref":"#/components/schemas/PanelAskAggregatingEvent"},{"$ref":"#/components/schemas/PanelAskResultEvent"},{"$ref":"#/components/schemas/PanelAskDoneEvent"}]},"PanelAskStartEvent":{"type":"object","required":["type","total"],"properties":{"type":{"type":"string","enum":["start"]},"total":{"type":"integer","description":"Total number of minds that will answer."}}},"PanelAskClassificationEvent":{"type":"object","required":["type","classification"],"properties":{"type":{"type":"string","enum":["classification"]},"classification":{"$ref":"#/components/schemas/PanelQuestionClassification"}}},"PanelAskAnswerEvent":{"type":"object","required":["type","sparkId","sparkName","groupId","groupName","answer"],"properties":{"type":{"type":"string","enum":["answer"]},"sparkId":{"type":"string","format":"uuid"},"sparkName":{"type":"string"},"discipline":{"type":["string","null"]},"profileImageUrl":{"type":["string","null"]},"groupId":{"type":"string","format":"uuid"},"groupName":{"type":"string"},"answer":{"type":"string"}}},"PanelAskAggregatingEvent":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["aggregating"]}}},"PanelAskResultEvent":{"type":"object","required":["type","outputData","outputType"],"properties":{"type":{"type":"string","enum":["result"]},"outputData":{"$ref":"#/components/schemas/PanelOutputData"},"outputType":{"type":"string","enum":["bar"]}}},"PanelAskDoneEvent":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["done"]}}},"PanelQuestionClassification":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["scale","categorical","qualitative"]},"scaleRange":{"type":"array","minItems":2,"maxItems":2,"items":{"type":"number"}},"options":{"type":"array","items":{"type":"string"}}}},"PanelOutputData":{"type":"object","required":["title","type","groups"],"properties":{"title":{"type":"string"},"type":{"type":"string","enum":["scale","categorical","qualitative"]},"classification":{"$ref":"#/components/schemas/PanelQuestionClassification"},"categoryCodebook":{"type":"array","items":{"$ref":"#/components/schemas/PanelCategoryCodebookEntry"}},"groups":{"type":"array","items":{"$ref":"#/components/schemas/PanelOutputGroup"}}}},"PanelCategoryCodebookEntry":{"type":"object","required":["label","originalLabels","count"],"properties":{"label":{"type":"string"},"originalLabels":{"type":"array","items":{"type":"string"}},"count":{"type":"integer","minimum":0}}},"PanelOutputGroup":{"type":"object","required":["group","value","answers"],"properties":{"group":{"type":"string"},"value":{"type":"string"},"alignmentScore":{"type":"integer","minimum":0,"maximum":100},"answers":{"type":"array","items":{"$ref":"#/components/schemas/PanelOutputAnswer"}}}},"PanelOutputAnswer":{"type":"object","required":["value","persona","message"],"properties":{"value":{"type":"string"},"rawValue":{"type":"string"},"persona":{"type":"string"},"discipline":{"type":["string","null"]},"message":{"type":"string"},"imageUrl":{"type":["string","null"]},"reliabilityScore":{"type":"integer","minimum":0,"maximum":100}}},"PanelExportRequest":{"type":"object","properties":{"kind":{"type":"string","enum":["executive_brief","full_report","raw_data"],"default":"full_report","description":"Export category."},"format":{"type":"string","enum":["pdf","md","docx","pptx","csv","xls"],"default":"md","description":"File format. Executive-summary and full-report PDFs queue branded PDF export jobs; other formats return an inline downloadable artifact."},"length":{"type":"string","enum":["short","standard","detailed"],"default":"standard","description":"Summary length for executive summary exports."}}},"PanelExportResponse":{"oneOf":[{"$ref":"#/components/schemas/PanelInlineExportResponse"},{"$ref":"#/components/schemas/PanelPdfExportJobResponse"}]},"PanelInlineExportResponse":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["kind","format","filename","mimeType"],"properties":{"kind":{"type":"string","enum":["executive_brief","full_report","raw_data"]},"format":{"type":"string","enum":["pdf","md","docx","pptx","csv","xls"]},"filename":{"type":"string"},"mimeType":{"type":"string"},"content":{"type":"string","description":"Text artifact content for Markdown, CSV, or XLS."},"contentBase64":{"type":"string","description":"Base64-encoded binary artifact for PDF, DOCX, or PPTX."}}}}},"PanelPdfExportJobResponse":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["kind","format","jobId","status"],"properties":{"kind":{"type":"string","enum":["executive_brief","full_report"]},"format":{"type":"string","enum":["pdf"]},"jobId":{"type":"string","description":"BullMQ export job ID."},"status":{"type":"string","enum":["queued"]}}}}},"PanelExportStatusResponse":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PanelExportStatus"}}},"PanelExportStatus":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["idle","queued","processing","completed","failed"]},"progress":{"type":"number","minimum":0,"maximum":100},"downloadUrl":{"type":"string","description":"Pre-signed or authenticated URL for the generated PDF."},"error":{"type":"string"},"generatedAt":{"type":["string","null"],"format":"date-time"}}},"PanelSummary":{"type":"object","required":["id","name","flowMode","createdAt","updatedAt","messageCount","groups"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"flowMode":{"type":"string","enum":["panel"],"description":"Always `panel` on this endpoint."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"messageCount":{"type":"integer"},"isLinkSharingEnabled":{"type":"boolean"},"publicShareId":{"type":["string","null"],"format":"uuid"},"groups":{"type":"array","items":{"type":"object","required":["id","name","sparkCount","sparks"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"sparkCount":{"type":"integer"},"sparks":{"type":"array","items":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"discipline":{"type":["string","null"]},"profileImageUrl":{"type":["string","null"],"format":"uri"}}}}}}}}},"PanelMind":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"discipline":{"type":["string","null"]},"profileImageUrl":{"type":["string","null"],"format":"uri"}}},"PanelGroup":{"type":"object","required":["id","name","sparks"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"sparks":{"type":"array","items":{"$ref":"#/components/schemas/PanelMind"}}}},"PanelCreated":{"type":"object","required":["id","name","flowMode","createdAt","isLinkSharingEnabled","publicShareId","groups"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"flowMode":{"type":"string","enum":["panel"]},"createdAt":{"type":"string","format":"date-time"},"isLinkSharingEnabled":{"type":"boolean"},"publicShareId":{"type":["string","null"],"format":"uuid"},"groups":{"type":"array","items":{"$ref":"#/components/schemas/PanelGroup"}}}},"PanelMessage":{"type":"object","required":["id","role","content","metadata","createdAt"],"properties":{"id":{"type":"string"},"role":{"type":"string"},"content":{"type":"string"},"metadata":{},"createdAt":{"type":"string","format":"date-time"}}},"PanelDetail":{"type":"object","required":["id","name","flowMode","createdAt","updatedAt","isLinkSharingEnabled","publicShareId","groups","messages"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"flowMode":{"type":"string","enum":["panel"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"isLinkSharingEnabled":{"type":"boolean"},"publicShareId":{"type":["string","null"],"format":"uuid"},"groups":{"type":"array","items":{"$ref":"#/components/schemas/PanelGroup"}},"messages":{"type":"array","items":{"$ref":"#/components/schemas/PanelMessage"}}}},"SparkDetail":{"type":"object","required":["id","name","description","type","tags","isPublic","isLinkSharingEnabled","knowledgeItemCount","readyToChat","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string"},"type":{"type":"string","enum":["creative","expert","user"]},"discipline":{"type":["string","null"]},"systemPrompt":{"type":"string","description":"Full generated system prompt defining the spark's persona."},"tags":{"type":"array","items":{"type":"string"}},"isPublic":{"type":"boolean"},"isLinkSharingEnabled":{"type":"boolean"},"publicShareId":{"type":["string","null"],"format":"uuid","description":"Public share token (present only when link sharing is enabled)."},"profileImageUrl":{"type":["string","null"],"format":"uri"},"phoneNumber":{"type":["string","null"]},"clonedVoiceStatus":{"type":["string","null"],"description":"Voice cloning status; null if not cloned."},"profitSplitOptIn":{"type":"boolean"},"knowledgeItemCount":{"type":"integer","description":"Number of portfolio/knowledge items attached."},"trainingStatus":{"type":["string","null"],"enum":["queued","running","completed","failed"],"description":"Current training lifecycle state. Poll GET /v1/sparks/{id}/training for full detail."},"readyToChat":{"type":"boolean","description":"True only when training has completed; a mind's id exists before it is ready."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"TrainingStatus":{"type":"object","required":["status","readyToChat"],"properties":{"status":{"type":"string","enum":["queued","running","completed","failed"],"description":"Training lifecycle state."},"readyToChat":{"type":"boolean","description":"True only when training has completed and the mind can answer."},"message":{"type":["string","null"],"description":"Human-readable progress / status message."},"startedAt":{"type":["string","null"],"format":"date-time","description":"When training started (null until running)."},"completedAt":{"type":["string","null"],"format":"date-time","description":"When training finished (completed or failed)."},"error":{"type":["object","null"],"description":"Present only when status is `failed`.","required":["code","retryable"],"properties":{"code":{"type":"string","enum":["COLLECTION_FAILED","PROFILE_GEN_FAILED","TIMEOUT","INTERNAL"]},"retryable":{"type":"boolean","description":"When true, POST /v1/sparks/{id}/retrain may recover the mind."}}}}},"SparkSummary":{"type":"object","required":["id","name","description","type","tags","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Spark ID."},"name":{"type":"string","description":"Spark display name."},"description":{"type":"string","description":"Short summary of the spark."},"type":{"type":"string","enum":["creative","expert","user"],"description":"Spark archetype."},"discipline":{"type":["string","null"],"description":"Area of expertise / domain."},"tags":{"type":"array","items":{"type":"string"},"description":"User-supplied tags (max 20)."},"profileImageUrl":{"type":["string","null"],"format":"uri","description":"Avatar image; resolved to an absolute URL."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Pagination":{"type":"object","required":["total","limit","offset"],"properties":{"total":{"type":"integer","description":"Total matching rows."},"limit":{"type":"integer","description":"Page size requested."},"offset":{"type":"integer","description":"Number of rows skipped."}}},"CreateSparkRequest":{"type":"object","required":["name","discipline"],"properties":{"name":{"type":"string","minLength":2,"maxLength":100,"description":"Spark display name."},"discipline":{"type":"string","description":"Area of expertise (e.g. \"Marketing\", \"Engineering\")."},"description":{"type":"string","description":"Short summary. Defaults to \"Created via API\"."},"mode":{"type":"string","enum":["keywords","clone","link","manual"],"default":"keywords","description":"Training mode."},"type":{"type":"string","enum":["creative","expert","user"],"default":"expert"},"keywords":{"type":"array","items":{"type":"string"},"description":"Required when `mode=keywords`."},"personaContext":{"type":"string","description":"Required when `mode=clone` (name + brief context of the person to emulate)."},"contextLink":{"type":"string","format":"uri","description":"Required when `mode=link` (URL the AI will scrape)."},"link":{"type":"string","format":"uri","description":"Deprecated alias for `contextLink`."},"tags":{"type":"array","items":{"type":"string"},"maxItems":20},"profileImageUrl":{"type":"string","format":"uri","description":"External avatar URL; downloaded and persisted to Supabase storage."},"generateImage":{"type":"boolean","description":"Trigger async AI profile-image generation after creation. Defaults to true for auto-training modes; pass false to opt out."},"cloneVoice":{"type":"boolean","description":"Trigger async voice cloning via YouTube + Fish Audio (experimental)."},"isLinkSharingEnabled":{"type":"boolean","description":"Enable link sharing; generates a `publicShareId`."},"locale":{"type":"string","description":"ISO 639-1 code for the auto-generated description language. Falls back to the user's preferredLanguage, then `en`."}}}},"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"Personal API key. Format: `Bearer minds_…_key`. Create one at https://getminds.ai/settings/api-keys."}}},"security":[{"ApiKeyAuth":[]}]}