Minds Team

Chat API

Interact with your minds through chat completions and multi-turn conversations.

Chat API

Send messages to your minds and receive AI-generated responses. The Chat API supports both stateless completions and stateful multi-turn conversations with automatic history management.

Create persistent conversations where the server manages history, context compression, and rolling summaries automatically. No need to send the full message history with each request.

Create a Chat

Create a new stateful conversation linked to a mind.

Endpoint: POST /api/v1/chats

Headers:

Authorization: Bearer minds_your_api_key
Content-Type: application/json

Request Body:

{
  "name": "My Conversation",
  "sparkId": "your-spark-id"
}
ParameterTypeRequiredDescription
namestringNoDisplay name for the chat (default: "API Chat")
sparkIdstringNoThe mind to chat with. If omitted, assign a mind later.
descriptionstringNoOptional description

Response (201):

{
  "data": {
    "id": "601af953-3837-49c1-a31e-4fdbfa82ac04",
    "name": "My Conversation",
    "description": null,
    "createdAt": "2026-04-04T12:45:24.078Z",
    "sparks": [
      {
        "id": "4774888e-0a03-40d7-979b-39b47c4c049c",
        "name": "Ada Lovelace",
        "discipline": "mathematician and computer scientist"
      }
    ]
  }
}

Send a Message

Send a message to an existing chat. The server automatically handles conversation history, context window compression, and rolling summaries.

Endpoint: POST /api/v1/chats/{chatId}/messages

Headers:

Authorization: Bearer minds_your_api_key
Content-Type: application/json

Request Body:

{
  "content": "What are the latest advancements in solar panel technology?"
}
ParameterTypeRequiredDescription
contentstringYesThe message text (alternatively use message)

Response:

{
  "content": "Recent advancements in solar panel technology include perovskite cells with 30%+ efficiency...",
  "messageId": "cmnkbsddh00033v01ptk9t4et"
}
FieldTypeDescription
contentstringThe mind's response
messageIdstringUnique ID of the saved message

Multi-Turn Example

With stateful chats, you just send the new message each time. The server remembers everything:

# Step 1: Create a chat
CHAT=$(curl -s -X POST "https://getminds.ai/api/v1/chats" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Research Session", "sparkId": "your-spark-id" }')

CHAT_ID=$(echo $CHAT | jq -r '.data.id')

# Step 2: Send messages (server manages history automatically)
curl -X POST "https://getminds.ai/api/v1/chats/$CHAT_ID/messages" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "content": "What are the top marketing trends?" }'

# Step 3: Follow up (the mind remembers the previous exchange)
curl -X POST "https://getminds.ai/api/v1/chats/$CHAT_ID/messages" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "content": "Which of those would work best on a small budget?" }'

How it works under the hood:

  • Every message is persisted to the database
  • The last 8 messages are sent in full context
  • Older messages are compressed into a rolling LLM summary
  • Conversations can run for weeks/months without hitting context limits

Stateless Completions

For single requests or when you want to manage conversation history yourself.

Send Message

Send messages to a mind and receive responses.

Endpoint: POST /api/v1/sparks/{sparkId}/completion

Headers:

Authorization: Bearer minds_your_api_key
Content-Type: application/json

Request Body

{
  "messages": [
    {
      "role": "user",
      "content": "What are the latest advancements in solar panel technology?"
    }
  ]
}

Parameters

ParameterTypeRequiredDescription
messagesarrayNoArray of message objects (user, assistant, or tool). Omit the field entirely or send an empty array to trigger the greeting bootstrap (see Initial Message below).
messages[].rolestringYesEither "user", "assistant", or "tool"
messages[].contentstringYesThe message text. Must be a non-empty string for user messages (whitespace is rejected with 400). Omit for tool role and use tool_call_id + content instead.
modelstringNoOverride the AI model used for this request. See model override below.
providerstringNoAI provider for the model override: openai, anthropic, or google. Auto-detected from model name when possible.
languagestringNoHint for response language. Supported: en, de, es, fr, zh, tr, ar. Strong personas (e.g. clones of public figures with a fixed native language) may continue to respond in their persona's language.
generateImagebooleanNoWhen true, enables AI image generation in the response if contextually appropriate
response_formatobjectNoRequest structured output. See structured output below.
toolsarrayNoArray of user-defined tool definitions. See tool calling below.
tool_choicestring|objectNoControl tool calling behavior. See tool choice modes.
parallel_tool_callsbooleanNoAllow multiple tool calls per turn (default: true).

Response

{
  "messageId": "msg_550e840029b141d4a716446655440000",
  "content": "Recent advancements in solar panel technology include perovskite cells with 30%+ efficiency, bifacial panels that capture light from both sides, and integrated storage systems...",
  "metadata": {
    "ragCitations": [
      {
        "id": "abc123",
        "displaySource": "Spark knowledge",
        "similarity": 0.89
      }
    ]
  }
}
FieldTypeDescription
messageIdstringUnique message identifier for tracking
contentstringThe mind's response text (JSON string when using structured output)
parsedobjectParsed JSON object (only present when using response_format)
tool_callsarrayArray of tool call requests (only present when user-defined tools are called). Each has: id, name, arguments
metadataobjectOptional metadata (citations, images, ideas)
metadata.ragCitationsarrayKnowledge sources and web search results used in the response

Single Message Example

Ask a single question:

curl -X POST "https://getminds.ai/api/v1/sparks/spark-id/completion" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "role": "user",
        "content": "What are the top 3 marketing trends for 2025?"
      }
    ]
  }'

Multi-Turn Conversation

Maintain conversation context by including previous messages:

curl -X POST "https://getminds.ai/api/v1/sparks/spark-id/completion" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "role": "user",
        "content": "What are the top marketing trends?"
      },
      {
        "role": "assistant",
        "content": "The top trends are AI personalization, short-form video, and community building..."
      },
      {
        "role": "user",
        "content": "How can I implement AI personalization on a budget?"
      }
    ]
  }'

Tips for Multi-Turn Conversations:

  • Include the full conversation history in each request
  • Order matters: messages should be in chronological order
  • Alternate between user and assistant roles
  • The last message should always be from user

File Attachments

Attach files, documents, images, and links to provide context for your minds. Minds receive the processed content as part of the conversation.

Attaching Files

Add files via the metadata.attachedFiles array in your user message:

curl -X POST "https://getminds.ai/api/v1/sparks/spark-id/completion" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "role": "user",
        "content": "Please review this document and summarize the key points",
        "metadata": {
          "attachedFiles": [
            {
              "url": "https://example.com/quarterly-report.pdf",
              "name": "Q4 2025 Report",
              "type": "application/pdf"
            },
            {
              "path": "uploads/meeting-notes.docx",
              "name": "Strategy Meeting Notes"
            }
          ]
        }
      }
    ]
  }'

Attachment Format

Each attachment object supports:

FieldTypeRequiredDescription
urlstringNo*External URL to file (HTTP/HTTPS)
pathstringNo*Supabase storage path (auto-signed)
namestringNoDisplay name for the file
typestringNoMIME type (e.g., application/pdf, image/png)
descriptionstringNoOptional description
transcriptionstringNoPre-transcribed audio/video content

Note: Provide either url OR path, not both.

Supported File Types

Documents:

  • PDF (.pdf) - Text extraction + OCR for scanned pages
  • Word (.docx) - Full text extraction
  • Text (.txt, .md) - Direct text content
  • CSV/Excel (.csv, .xlsx) - Table extraction

Images:

  • PNG, JPG, WEBP - OCR + visual analysis
  • Vision capabilities for image understanding

External URLs:

  • Web pages fetched with Firecrawl (JS rendering + screenshots)
  • Automatic markdown conversion

Processing

Files are automatically processed before being sent to the mind:

  1. Download - Files fetched from URL or Supabase storage
  2. Extract - Content extracted (text from PDFs, OCR from images, etc.)
  3. Inject - Processed content added to conversation context
  4. Response - Mind sees both your message and the file content

Processing limits:

  • Timeout: 30 seconds per file
  • Files processed in parallel
  • Failed files show graceful fallback messages

Multiple File Example

{
  "messages": [
    {
      "role": "user",
      "content": "Compare these two proposals and recommend which one to pursue",
      "metadata": {
        "attachedFiles": [
          {
            "url": "https://example.com/proposal-a.pdf",
            "name": "Proposal A - Cloud Migration",
            "type": "application/pdf"
          },
          {
            "url": "https://example.com/proposal-b.pdf",
            "name": "Proposal B - On-Prem Upgrade",
            "type": "application/pdf"
          },
          {
            "path": "uploads/budget-analysis.xlsx",
            "name": "Budget Comparison"
          }
        ]
      }
    }
  ]
}

File Attachments in Conversation History

When continuing a conversation with file attachments, include the original message with attachments in the history:

{
  "messages": [
    {
      "role": "user",
      "content": "Analyze this sales data",
      "metadata": {
        "attachedFiles": [
          {
            "url": "https://example.com/sales-q4.csv",
            "name": "Q4 Sales Data"
          }
        ]
      }
    },
    {
      "role": "assistant",
      "content": "Based on the Q4 sales data, I can see that revenue increased by 23% compared to Q3..."
    },
    {
      "role": "user",
      "content": "What were the top 3 performing products?"
    }
  ]
}

Note: Files are only processed once when first attached. Subsequent messages in the same conversation reference the already-processed content.

For web pages and external content, use the url field:

{
  "messages": [
    {
      "role": "user",
      "content": "Summarize the key findings from this research paper",
      "metadata": {
        "attachedFiles": [
          {
            "url": "https://arxiv.org/pdf/2103.12345.pdf",
            "name": "AI Research Paper",
            "type": "application/pdf"
          }
        ]
      }
    }
  ]
}

For web pages specifically:

  • JavaScript-heavy sites are rendered with Firecrawl
  • Screenshots captured for visual context
  • Content converted to clean markdown

Error Handling

If file processing fails:

  • Mind receives a fallback message indicating the file was attached but processing failed
  • Conversation continues normally
  • Timeout errors show [Processing timeout - file may be too large]
  • Other errors show [Processing failed - file uploaded but analysis unavailable]

This ensures minds are aware of attempted attachments even if processing fails.

Initial Message (Greeting)

If you send an empty messages array or no messages, the mind will introduce itself:

curl -X POST "https://getminds.ai/api/v1/sparks/spark-id/completion" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": []
  }'

Response:

{
  "content": "Hi! I'm Sarah, a marketing director with 15 years of experience in B2B SaaS. I specialize in growth marketing and data-driven strategies. What can I help you with today?"
}

Model Override

You can optionally override the AI model used for a completion request by passing the model parameter. This is useful for benchmarking, cost optimization, or testing different model behaviors.

curl -X POST "https://getminds.ai/api/v1/sparks/spark-id/completion" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "role": "user",
        "content": "What are your thoughts on sustainable packaging?"
      }
    ],
    "model": "gpt-4o-mini"
  }'

When no model is specified, the server default is used.

Providers

ProviderValueExample Models
OpenAIopenaigpt-5.4, gpt-5.3, gpt-5-mini, gpt-4o, gpt-4o-mini, o3, o3-pro, o3-mini, o4-mini
Anthropicanthropicclaude-opus-4-6, claude-sonnet-4-6, claude-haiku-4-5
Googlegooglegemini-3.1-pro-preview, gemini-3-flash-preview, gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite

You can pass any model string supported by the provider. The provider is auto-detected from common model name prefixes (claude- → Anthropic, gemini- → Google, gpt-/o1/o3/o4 → OpenAI).

For models with ambiguous names, specify the provider explicitly:

{
  "messages": [...],
  "model": "my-custom-fine-tune",
  "provider": "openai"
}

If the provider cannot be determined, the API returns a 400 Bad Request error asking you to specify it.

Structured Output

Request guaranteed JSON responses that match a specific schema using the response_format parameter. This follows the OpenAI-style structured output pattern and is useful for extracting structured data from conversations.

JSON Schema Mode

Force the model to output valid JSON matching your schema:

curl -X POST "https://getminds.ai/api/v1/sparks/spark-id/completion" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "role": "user",
        "content": "Analyze the sentiment of this text: I love this product, it exceeded all my expectations!"
      }
    ],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "sentiment_analysis",
        "description": "Sentiment analysis result",
        "schema": {
          "type": "object",
          "properties": {
            "sentiment": {
              "type": "string",
              "enum": ["positive", "negative", "neutral"]
            },
            "confidence": {
              "type": "number",
              "minimum": 0,
              "maximum": 1
            },
            "keywords": {
              "type": "array",
              "items": { "type": "string" }
            }
          },
          "required": ["sentiment", "confidence", "keywords"]
        }
      }
    }
  }'

Response:

{
  "content": "{\"sentiment\": \"positive\", \"confidence\": 0.95, \"keywords\": [\"love\", \"exceeded\", \"expectations\"]}",
  "parsed": {
    "sentiment": "positive",
    "confidence": 0.95,
    "keywords": ["love", "exceeded", "expectations"]
  }
}

JSON Object Mode

Force JSON output without schema validation:

curl -X POST "https://getminds.ai/api/v1/sparks/spark-id/completion" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "role": "user",
        "content": "List 3 marketing ideas as JSON"
      }
    ],
    "response_format": {
      "type": "json_object"
    }
  }'

Response Format Types

TypeDescription
textDefault text output (current behavior)
json_objectForces valid JSON output without schema validation
json_schemaForces JSON output matching the provided schema

JSON Schema Fields

FieldTypeRequiredDescription
namestringYesIdentifier for the schema
descriptionstringNoDescription of what the schema represents
schemaobjectYesJSON Schema definition
strictbooleanNoEnforce strict schema adherence (default: true)

Supported Schema Features

The following JSON Schema features are supported:

  • Types: string, number, integer, boolean, array, object, null
  • Constraints: enum, minimum, maximum, minLength, maxLength, minItems, maxItems
  • Structure: properties, required, items, additionalProperties
  • Metadata: description (used to guide the model)

Notes

  • Tools (RAG, web search, etc.) work with structured output — the mind can still search its knowledge base before generating the structured response
  • The parsed field contains the parsed JSON object for convenience; content contains the raw JSON string
  • All major providers (OpenAI, Anthropic, Google) support structured output
  • For complex schemas, consider adding description fields to guide the model's output

Tool Calling

Enable minds to call your custom functions during conversations. This follows the OpenAI-compatible function calling pattern and lets you extend minds' capabilities with external tools and APIs.

How It Works

  1. Define tools: Pass tool definitions with names, descriptions, and JSON Schema parameters
  2. Mind decides: The mind determines when to call your tools based on the conversation (or you force it with tool_choice)
  3. API returns tool calls: The response includes tool_calls with the tool name and generated arguments
  4. Execute tools: You run the tools in your application and get the results
  5. Send results back: Include tool results in the next message with role: "tool"
  6. Mind responds: The mind incorporates the tool results into its final response

Basic Example

Request with tools:

curl -X POST "https://getminds.ai/api/v1/sparks/spark-id/completion" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "role": "user",
        "content": "What is the weather in Berlin?"
      }
    ],
    "tools": [
      {
        "name": "get_weather",
        "description": "Get current weather for a city",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {
              "type": "string",
              "description": "City name"
            },
            "units": {
              "type": "string",
              "enum": ["celsius", "fahrenheit"],
              "description": "Temperature units"
            }
          },
          "required": ["city"]
        }
      }
    ]
  }'

Response:

{
  "content": "",
  "tool_calls": [
    {
      "id": "call_abc123",
      "name": "get_weather",
      "arguments": {
        "city": "Berlin",
        "units": "celsius"
      }
    }
  ]
}

Execute the tool and send results back:

curl -X POST "https://getminds.ai/api/v1/sparks/spark-id/completion" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "role": "user",
        "content": "What is the weather in Berlin?"
      },
      {
        "role": "assistant",
        "content": "",
        "tool_calls": [
          {
            "id": "call_abc123",
            "name": "get_weather",
            "arguments": {
              "city": "Berlin",
              "units": "celsius"
            }
          }
        ]
      },
      {
        "role": "tool",
        "tool_call_id": "call_abc123",
        "content": "{\"temperature\": 18, \"condition\": \"partly cloudy\", \"humidity\": 65}"
      }
    ],
    "tools": [
      {
        "name": "get_weather",
        "description": "Get current weather for a city",
        "parameters": {
          "type": "object",
          "properties": {
            "city": { "type": "string" },
            "units": { "type": "string", "enum": ["celsius", "fahrenheit"] }
          },
          "required": ["city"]
        }
      }
    ]
  }'

Final response:

{
  "content": "The current weather in Berlin is 18°C and partly cloudy, with 65% humidity."
}

Tool Definition Schema

Each tool must follow this structure:

{
  "name": "tool_name",
  "description": "Clear description of when and how to use this tool",
  "parameters": {
    "type": "object",
    "properties": {
      "param1": {
        "type": "string",
        "description": "What this parameter does"
      }
    },
    "required": ["param1"]
  },
  "strict": true
}

Required fields:

FieldTypeDescription
namestringFunction name. Must be unique and cannot conflict with internal tools.
descriptionstringClear description of what the tool does and when to use it. This guides the mind's tool selection.
parametersobjectJSON Schema defining the function arguments.

Optional fields:

FieldTypeDefaultDescription
strictbooleantrueEnforce strict schema validation for arguments.

Tool Choice Modes

Control when and how the mind calls tools using the tool_choice parameter:

ValueBehavior
"auto"Mind decides whether to call tools (default)
"required"Mind must call at least one tool before responding
"none"Disable tool calling for this turn
{"name": "tool_name"}Force the mind to call a specific tool

Examples:

// Let the mind decide
{
  "messages": [...],
  "tools": [...],
  "tool_choice": "auto"
}

// Force a specific tool
{
  "messages": [...],
  "tools": [...],
  "tool_choice": {
    "name": "search_database"
  }
}

// Require at least one tool call
{
  "messages": [...],
  "tools": [...],
  "tool_choice": "required"
}

Parallel Tool Calls

By default, minds can call multiple tools in a single turn for efficiency:

{
  "content": "",
  "tool_calls": [
    {
      "id": "call_1",
      "name": "get_customer",
      "arguments": { "id": "CUST-001" }
    },
    {
      "id": "call_2",
      "name": "get_customer",
      "arguments": { "id": "CUST-002" }
    }
  ]
}

To disable parallel calls and force sequential execution:

{
  "messages": [...],
  "tools": [...],
  "parallel_tool_calls": false
}

Tool Message Format

When sending tool results back, use the tool role:

{
  "role": "tool",
  "tool_call_id": "call_abc123",
  "content": "{\"result\": \"success\", \"data\": {...}}"
}
FieldTypeRequiredDescription
rolestringYesMust be "tool"
tool_call_idstringYesThe id from the tool call in the assistant's response
contentstringYesTool execution result (typically JSON string)

Internal vs User Tools

Minds has built-in server-side tools that execute automatically:

Internal ToolPurpose
GET_SPARK_RAGSearch the mind's knowledge base
WEB_SEARCHSearch the web
GENERATE_IMAGEGenerate images with AI
DISPLAY_IMAGEDisplay images from the mind's memory
DOCUMENT_PROCESSINGAnalyze uploaded files
ANALYZE_LINKFetch and analyze web URLs

Key differences:

  • Internal tools: Execute server-side, results included in content and metadata. Never returned in tool_calls.
  • User tools: Returned in tool_calls for you to execute. Results must be sent back as tool messages.

You cannot override or disable internal tools. User tools are additive — they extend the mind's capabilities.

Complete Multi-Tool Example

A legal assistant mind with multiple custom tools:

curl -X POST "https://getminds.ai/api/v1/sparks/spark-id/completion" \
  -H "Authorization: Bearer minds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "role": "user",
        "content": "Create a new case for Schmidt vs. Mueller and search for similar precedents"
      }
    ],
    "tools": [
      {
        "name": "create_case",
        "description": "Create a new legal case in the system",
        "parameters": {
          "type": "object",
          "properties": {
            "title": {
              "type": "string",
              "description": "Case title (parties involved)"
            },
            "practice_area": {
              "type": "string",
              "enum": ["corporate", "litigation", "employment", "ip"],
              "description": "Legal practice area"
            },
            "client_id": {
              "type": "string",
              "description": "Client identifier"
            }
          },
          "required": ["title", "practice_area"]
        }
      },
      {
        "name": "search_precedents",
        "description": "Search legal database for similar cases",
        "parameters": {
          "type": "object",
          "properties": {
            "keywords": {
              "type": "array",
              "items": { "type": "string" },
              "description": "Search keywords"
            },
            "practice_area": {
              "type": "string",
              "description": "Filter by practice area"
            },
            "max_results": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "description": "Maximum number of results"
            }
          },
          "required": ["keywords"]
        }
      }
    ],
    "parallel_tool_calls": true
  }'

Response with parallel tool calls:

{
  "content": "",
  "tool_calls": [
    {
      "id": "call_1",
      "name": "create_case",
      "arguments": {
        "title": "Schmidt vs. Mueller",
        "practice_area": "litigation"
      }
    },
    {
      "id": "call_2",
      "name": "search_precedents",
      "arguments": {
        "keywords": ["Schmidt", "Mueller"],
        "practice_area": "litigation",
        "max_results": 10
      }
    }
  ]
}

Best Practices

  1. Write clear descriptions: The description field is critical. Be specific about when and why to use each tool.
    "description": "Search database"
    "description": "Search the legal precedents database for similar cases based on keywords and practice area"
    
  2. Use parameter descriptions: Help the mind understand what each parameter does.
    "case_id": {
      "type": "string",
      "description": "Unique case identifier in format CASE-YYYY-NNNN"
    }
    
  3. Leverage enums for constrained values:
    "status": {
      "type": "string",
      "enum": ["pending", "active", "closed", "archived"]
    }
    
  4. Set validation constraints:
    "priority": {
      "type": "integer",
      "minimum": 1,
      "maximum": 5,
      "description": "Priority level (1=lowest, 5=highest)"
    }
    
  5. Enable strict mode: Keep strict: true (default) to ensure the mind generates valid arguments.
  6. Return structured tool results: Use JSON for tool results to make them easy to parse:
    {
      "role": "tool",
      "tool_call_id": "call_123",
      "content": "{\"success\": true, \"case_id\": \"CASE-2026-001\", \"created_at\": \"2026-03-30T23:00:00Z\"}"
    }
    
  7. Handle errors gracefully: Return error details in the tool result:
    {
      "role": "tool",
      "tool_call_id": "call_123",
      "content": "{\"success\": false, \"error\": \"Case already exists\", \"error_code\": \"DUPLICATE_CASE\"}"
    }
    

Limitations

  • Maximum 128 tools per request
  • Tool names must be unique and cannot conflict with internal tool names
  • Tool execution happens client-side — you are responsible for running and securing your tools
  • Tool results must be sent back in the conversation history for the mind to respond

JSON Schema Support

The parameters field supports standard JSON Schema features:

Types:

  • string, number, integer, boolean, array, object, null

Validation:

  • enum — Restrict to specific values
  • minimum, maximum — Numeric bounds
  • minLength, maxLength — String length
  • minItems, maxItems — Array size
  • pattern — Regex validation
  • format — String formats (e.g., "date-time", "email", "uri")

Structure:

  • properties — Object properties
  • required — Required fields
  • items — Array item schema
  • additionalProperties — Allow/disallow extra properties

Example with advanced validation:

{
  "name": "schedule_meeting",
  "description": "Schedule a meeting with a client",
  "parameters": {
    "type": "object",
    "properties": {
      "title": {
        "type": "string",
        "minLength": 1,
        "maxLength": 200
      },
      "date": {
        "type": "string",
        "format": "date-time",
        "description": "Meeting date and time in ISO 8601 format"
      },
      "attendees": {
        "type": "array",
        "items": {
          "type": "string",
          "format": "email"
        },
        "minItems": 1,
        "maxItems": 20
      },
      "duration_minutes": {
        "type": "integer",
        "minimum": 15,
        "maximum": 480,
        "description": "Meeting duration (15-480 minutes)"
      }
    },
    "required": ["title", "date", "attendees"]
  }
}

How It Works

1. Context Loading

When you send a message, the mind:

  • Loads its system prompt and configuration
  • Automatically searches its knowledge base for relevant information
  • Considers the conversation history

2. Processing

The mind:

  • Analyzes your message in context
  • Grounds responses in retrieved knowledge with citations
  • Accesses additional tools (web search, image generation, etc.) if needed
  • Formulates a response aligned with its personality

3. Response Generation

The mind:

  • Generates a response that reflects its expertise
  • Includes citations when using knowledge base or web sources
  • Returns the message with optional metadata (citations, images, etc.)

Metadata

Responses can include additional metadata:

Images

When a mind generates or displays images:

{
  "content": "Here are some logo concepts...",
  "metadata": {
    "images": [
      {
        "id": "img_123",
        "url": "https://...",
        "filename": "Logo Concept 1",
        "description": "Modern minimalist logo with blue gradient",
        "source": "generated"
      }
    ]
  }
}

Ideas

When a mind creates flow ideas:

{
  "content": "I've created a campaign concept...",
  "metadata": {
    "ideas": [
      {
        "id": "idea_123",
        "title": "Summer Campaign 2025",
        "description": "Eco-friendly summer campaign targeting millennials",
        "status": "draft"
      }
    ]
  }
}

Knowledge Citations

When a mind retrieves information from its knowledge base or web search:

{
  "content": "Based on recent research, solar panel efficiency has improved significantly...",
  "metadata": {
    "ragCitations": [
      {
        "id": "9bf44ab0-9d83-42ec-b941-c0ab7610e949",
        "displaySource": "Spark knowledge",
        "similarity": 0.85
      },
      {
        "id": "external-web-123",
        "displaySource": "https://example.com/solar-research",
        "similarity": 0.92
      }
    ]
  }
}

Citation Fields:

  • id - Unique identifier for the source
  • displaySource - Human-readable source name or URL
  • similarity - Relevance score (0-1) indicating how well the source matches the query

Minds automatically search their knowledge base before responding and include citations when grounding their answers in specific sources.

Access Control

You can chat with minds you:

  • Own - Minds you created
  • Have access to - Minds shared with you by team members
  • Are a member of - Minds in team workspaces you belong to
  • Public minds - Publicly accessible minds

Attempting to access unauthorized minds returns:

{
  "statusCode": 403,
  "statusMessage": "Access denied"
}

Response Formats

Text Response

Most responses are plain text:

{
  "content": "Based on current trends, I recommend focusing on..."
}

Structured Response

Some minds may return structured content:

{
  "content": "Here's my analysis:\n\n1. Trend: AI Personalization\n   - Impact: High\n   - Timeline: 6-12 months\n\n2. Trend: Short-form Video\n   - Impact: Very High\n   - Timeline: Immediate"
}

Empty Response with Metadata

Sometimes only metadata is returned (e.g., for image generation):

{
  "content": "",
  "metadata": {
    "images": [...]
  }
}

Best Practices

Be Specific

❌ "Tell me about marketing"
✅ "What are the most cost-effective digital marketing channels for a B2B SaaS startup with a $5K monthly budget?"

Provide Context

✅ "We're launching a sustainable fashion brand targeting Gen Z. What social media strategy would you recommend?"

Use Follow-ups

Take advantage of conversation memory:

User: "What are the top trends?"
Assistant: "The top trends are..."
User: "Which of these would work best for a small budget?"
Assistant: "For a small budget, I'd focus on..."

Reference Knowledge

If you've uploaded knowledge, reference it:

✅ "Based on our brand guidelines, what tone should we use for this campaign?"

Error Responses

400 Bad Request

Missing or invalid spark ID:

{
  "statusCode": 400,
  "statusMessage": "Spark ID is required"
}

Unsupported provider:

{
  "statusCode": 400,
  "statusMessage": "Unsupported provider: 'invalid'. Supported providers: openai, anthropic, google."
}

Ambiguous model name without provider:

{
  "statusCode": 400,
  "statusMessage": "Cannot auto-detect provider for model 'my-model'. Please specify a 'provider' parameter (openai, anthropic, or google)."
}

401 Unauthorized

Invalid API key.

403 Forbidden

Access denied to spark:

{
  "statusCode": 403,
  "statusMessage": "Access denied"
}

404 Not Found

Spark doesn't exist:

{
  "statusCode": 404,
  "statusMessage": "Spark not found"
}

Usage Notes

  • The API does not currently enforce rate limits
  • However, please be respectful of server resources
  • Excessive usage may result in throttling or account suspension

Next Steps