Minds API Integration Guide for AI Agents
Agent-oriented guide to discovering, authenticating, safely calling, retrying, polling, and presenting Minds v1 API workflows.
This guide is the operating contract for an AI agent that calls the Minds v1 REST API. It complements the OpenAPI document, complete endpoint catalog, and domain walkthroughs.
Choose REST or MCP
| Need | Prefer | Why |
|---|---|---|
| Generate a typed SDK, run a backend integration, or control HTTP details | v1 REST API | Stable resource URLs, response envelopes, streaming, and durable job endpoints |
| Let ChatGPT, Claude, Cursor, or another compatible assistant select research tools | MCP | Protocol-native tool schemas, annotations, OAuth, widgets, and presentation contracts |
| Build a long-running service that resumes after process restarts | v1 REST API | Persist run, Study, draft, and export IDs in your own job state |
| Run research interactively from a user conversation | MCP | Tool descriptions encode routing, confirmation, and safe presentation behavior |
Both surfaces call the same v1 application boundaries for supported research actions. Do not combine REST and MCP in the same logical operation unless you have an explicit reason and a stable resource ID.
Discovery checklist
Read these resources before generating code or planning calls:
https://getminds.ai/_openapi.json— live OpenAPI 3.1 document for routes with detailed operation metadata.https://getminds.ai/api/reference— complete v1 route catalog, including routes whose detailed OpenAPI schemas are still being expanded.https://getminds.ai/api/errors— error envelope, plan limits, and retry behavior.https://getminds.ai/llms.txtandhttps://getminds.ai/llms-full.txt— agent-oriented documentation discovery and consolidated reference text.https://getminds.ai/mcp/agents— use this instead when your host supports MCP tools.
Do not infer that a route is unavailable merely because it is not yet present in the generated OpenAPI document. The endpoint catalog is the completeness authority; the OpenAPI document is the schema authority for operations it includes.
Authentication and secret handling
Send a personal Minds API key as a bearer token:
Authorization: Bearer minds_…
Agent rules:
- Read the key from a secret manager or environment variable. Never place it in prompts, source code, URLs, logs, traces, or error messages.
- Use separate keys for development and production.
- Treat the value returned by
POST /api/v1/api-keysas write-only: it is shown once. - Do not let an autonomous agent rotate or revoke the key it is currently using.
- On
401, stop and request credential repair. Do not repeatedly retry. - On
403, do not disguise an access-policy failure as “not found.” Explain that the authenticated account lacks access.
Stable request wrapper
Centralize authentication, JSON handling, timeouts, and error parsing:
const MINDS_BASE_URL = 'https://api.getminds.ai/v1'
type MindsError = {
statusCode?: number
statusMessage?: string
message?: string
data?: unknown
}
async function mindsRequest<T>(
path: string,
init: RequestInit = {},
): Promise<T> {
const response = await fetch(`${MINDS_BASE_URL}${path}`, {
...init,
headers: {
Authorization: `Bearer ${process.env.MINDS_API_KEY}`,
...(init.body ? { 'Content-Type': 'application/json' } : {}),
...init.headers,
},
signal: init.signal ?? AbortSignal.timeout(120_000),
})
const contentType = response.headers.get('content-type') || ''
const payload = contentType.includes('application/json')
? await response.json()
: await response.text()
if (!response.ok) {
const error = payload as MindsError
throw new Error(
`Minds ${response.status}: ${error.message || error.statusMessage || response.statusText}`,
)
}
return payload as T
}
Use the apex form (https://getminds.ai/api/v1) if your infrastructure does not follow same-origin 307 redirects for API-subdomain GET requests.
Plan before mutating
Classify each proposed call:
| Class | Examples | Agent behavior |
|---|---|---|
| Read-only | List/read resources, status, analytics, methods | May call when needed to answer the request |
| Reversible creation/update | Create a private draft, update a name | State the intended target; preserve returned IDs |
| Costly execution | Ask a Panel, run a Study, retrain, regenerate | Ensure it matches the user's request and avoid duplicate calls |
| Public exposure | Enable link sharing | Require explicit intent; explain what becomes public |
| Destructive | Delete Minds, Groups, Panels, chats, Formations, drafts | Obtain explicit confirmation of exact IDs immediately before the call |
| Credential control | Mint/revoke API keys | Keep outside autonomous research flows |
Never enable isLinkSharingEnabled merely to make a result convenient to access. Private is the default.
Use IDs as durable state
Names are suitable for user interaction, but IDs are the integration contract. Persist:
sparkIdafter Mind creation;groupIdafter Group creation;panelIdafter Panel creation;draftPlanIdandrevisionduring research planning;studyIdorrunIdduring execution;jobIdfor exports;itemIdfor knowledge ingestion;draftIdandexpectedRevisionfor sidebar Study drafts.
Do not re-list by fuzzy name after a successful create response. Doing so can select the wrong resource when names are duplicated.
Asynchronous operations
Several operations return before work is complete.
| Start operation | Persist | Poll/read |
|---|---|---|
| Create Mind | sparkId | GET /sparks/{sparkId}/training |
| Create grounded Group | groupId | GET /groups/{id}/progress |
| Add file/link knowledge | itemId | GET /sparks/{sparkId}/knowledge/{itemId}/status |
| Ask Panel in queued mode | runId | GET /runs/{runId} and /events |
| Run confirmed Study | studyId | GET /panels/{panelId}/studies/{studyId} |
| Export | jobId | entity-specific export-status, then export-download |
Recommended polling behavior:
- Honor
Retry-Afterwhen returned. - Otherwise start at 1–2 seconds and exponentially back off to 10–15 seconds.
- Add jitter when many jobs run concurrently.
- Persist the last event cursor for
/runs/{runId}/events. - Stop on terminal success, failure, cancellation, or
plan_limited. - Set a workflow-level deadline; a client timeout does not prove the server operation failed.
Idempotency and retries
- Retry
GETrequests after transient429,502,503, or504responses using bounded exponential backoff. - Retry a mutation only when the endpoint documents idempotency or you supplied a stable idempotency key.
create_group_from_briefderives an idempotency key from its arguments. Retry with exactly the same arguments after a timeout to recover the original Group.run_panel_studysupports an explicit stable idempotency key through MCP; REST callers should preserve the confirmed draft ID/revision and returned Study ID.- Optimistic-concurrency failures on Study drafts require a fresh read and human/agent reconciliation. Do not overwrite with a guessed revision.
- Never retry destructive calls merely because the client did not receive the response. Read the resource first to determine whether deletion already succeeded.
Direct questions versus guided Studies
Use this routing table:
| User request | Route |
|---|---|
| One direct question to an existing Panel | POST /panels/{panelId}/ask |
| Knowledge-only durable direct run | POST /panels/{panelId}/runs |
| Multiple questions, a broad objective, an asset audit, structured evidence outputs, or an explicit method | Plan → confirm → Study lifecycle |
| Export existing evidence | POST /panels/{panelId}/export |
| Show existing evidence differently | Read status/summary/analytics; do not recruit a new run |
The guided lifecycle is:
POST research-plans/preview
-> present the exact draft and every confirmation question
-> revise the same draft if the user changes or answers anything
-> receive explicit confirmation of the exact revision
-> POST studies with that draft ID and revision
-> poll GET studies/{studyId}
-> GET or POST summary
Planning is non-executing. Never claim that research has started after a preview call.
Method availability
Call GET /api/v1/research-methods before promising a named method. Treat fields as follows:
executable: true— the registered server adapter can run the method.executable: false— the method may be represented or planned but is not an execution promise.- Advanced methods require explicit opt-in at execution time.
- Preserve deterministic calculations returned by the Study endpoint; do not recompute them with an LLM.
File and URL inputs
- Upload interactive browser files with multipart form data.
- For autonomous agents, prefer public, short-lived signed, or Minds workspace-upload URLs.
- Do not embed large binary files as base64 JSON.
- Give every file a meaningful
nameand MIMEtypewhen known. - URLs may be rejected by SSRF and redirect guards even when they are syntactically valid.
- Knowledge retrieval is bounded to 50 MB and a server timeout; split larger sources before ingestion.
- For respondent datasets, preview segmentation before creating a representative cohort.
Error decisions
| Signal | Meaning | Agent response |
|---|---|---|
400 / validation details | Request does not satisfy the schema | Correct the payload; do not retry unchanged |
401 | Missing/invalid/expired credential | Stop and repair authentication |
403 | Authenticated but not allowed | Explain access/ownership/plan boundary |
404 | Resource is absent or not visible | Verify the persisted ID and account context |
409 | Revision/idempotency/state conflict | Read current state and reconcile |
415 | Unsupported request media type | Correct Content-Type or file form |
429 | Rate or usage limit | Honor Retry-After; distinguish rate limiting from plan_limited |
plan_limited before execution | Nothing started | Explain the required plan/allowance change |
status: plan_limited during a Study | Partial artifacts were preserved | Report completed versus remaining questions; never call it complete |
5xx | Transient or server failure | Bounded retry for safe/idempotent calls, otherwise read state first |
Result presentation
- Preserve citations, source URLs, shared links, download links, and resource IDs exactly.
- Clearly label synthetic responses and distinguish them from primary human research.
- Report status as queued/running/partial/completed/failed based on returned fields, not elapsed time.
- For categorical or multiselect results, preserve the server's aggregation semantics instead of forcing percentages to sum to 100 when multiple selections are allowed.
- Do not invent missing Mind answers or fill incomplete Study artifacts.
- Use the authenticated workspace link for the owner and a returned shared link only for external handoff.
Minimal autonomous Panel example
const panels = await mindsRequest<{ data: Array<{ id: string; name: string }> }>(
'/panels',
)
const panel = panels.data.find(item => item.name === 'Launch research')
if (!panel) throw new Error('Panel not found')
const started = await mindsRequest<{ data: { runId: string } }>(
`/panels/${panel.id}/runs`,
{
method: 'POST',
body: JSON.stringify({
question: 'What are the strongest objections to this positioning?',
sourcePolicy: 'knowledge_only',
}),
},
)
// Persist started.data.runId before polling.
Preflight checklist
Before a mutation, verify:
- the authenticated workspace and plan context;
- exact resource IDs and ownership/access;
- whether the request is direct research or requires a confirmed plan;
- whether sharing remains private;
- whether a previous timed-out call may already have succeeded;
- whether the operation consumes an allowance or triggers generation;
- whether explicit confirmation is required.
After a mutation, persist returned IDs, poll the documented status endpoint, and present only terminal or explicitly partial results.