1. Threads
  2. Send Message
POST
/threads/messages
curl --request POST \
     --url https://app.backboard.io/api/threads/messages \
     --header 'X-API-Key: <api-key>' \
     --header 'authorization: <authorization>' \
     --header 'x_session_token: <x_session_token>' \
     --header 'Content-Type: application/json' \
     --data '{
  "thread_id": "<uuid>",
  "assistant_id": "<uuid>",
  "content": "string",
  "system_prompt": "string",
  "llm_provider": "string",
  "model_name": "string",
  "image_generation": "off",
  "image_model_provider": "string",
  "image_model_name": "string",
  "stream": false,
  "thinking": {
    "effort": "low",
    "budget_tokens": 0,
    "max_tokens": 1,
    "exclude_reasoning": true
  },
  "tools": [
    {}
  ],
  "memory": "off",
  "memory_response_citation": false,
  "memory_citation": false,
  "memory_pro": "string",
  "web_search": "off",
  "send_to_llm": "true",
  "json_output": false,
  "custom_timestamp": "<date-time>",
  "metadata": "string",
  "voice": {},
  "video_generation": "off",
  "video_model_provider": "string",
  "video_model_name": "string",
  "video_config": {
    "duration": 1,
    "resolution": "string",
    "aspect_ratio": "string",
    "size": "string",
    "generate_audio": true,
    "seed": 1,
    "provider": {},
    "upscale_factor": 0,
    "creativity": 1
  },
  "image_config": {
    "resolution": "string",
    "aspect_ratio": "string",
    "size": "string",
    "quality": "string",
    "background": "string",
    "output_format": "string",
    "output_compression": 0,
    "n": 1,
    "seed": 1,
    "provider": {}
  },
  "operation": "chat",
  "system_one": {
    "questions": {
      "additionalProperty": {
        "instructions": "string",
        "type": "string",
        "criteria": {
          "true": "string",
          "false": "string"
        }
      }
    },
    "state": "string"
  }
}'

​
Overview

The recommended way to send a message. No pre-created assistant or thread required.

  • Omit thread_id → a new thread (and default assistant) are auto-created. The response returns thread_id and assistant_id so you can continue the conversation.
  • Pass thread_id → message is appended to the existing thread (stateful continuation).
  • Pass assistant_id → new threads are created under that assistant, sharing its memory, documents, and stored config.
  • Pass system_prompt → applies to this request; falls back to the assistant’s stored description if omitted.
  • Pass tools → tool definitions for this request (OpenAI-style).

​
Quick Start

For TypeSafe Jev, use llm_provider="typesafe", model_name="jev-latest", and system_one={"questions": {...}} on this same endpoint. Responses preserve normal thread/message IDs and billing, with typed answers in system_one. Use stream=false. See System One Models for question types, SDK examples, and conversation-state behavior.

For media without a chat-model call, set operation="generate_image" or "generate_video". Reuse the corresponding image/video model and config fields. See Stateless Calls for setup, Stateless Image API for image recipes, and Stateless Video API for frame, source-video, and reference combinations. Omit operation to keep normal chat behavior.

from backboard import BackboardClient

client = BackboardClient(api_key="YOUR_API_KEY")

# First message — thread auto-created
r = await client.send_message("Hello! Tell me a fun fact.")
print(r.content)
print(r.thread_id)      # save this to continue
print(r.assistant_id)

# Continue on the same thread
r2 = await client.send_message(
    "Tell me another!",
    thread_id=r.thread_id,
)
print(r2.content)

​
Streaming

async for chunk in await client.send_message(
    "Tell me a story",
    stream=True,
):
    if chunk.get("type") == "content_streaming":
        print(chunk.get("content", ""), end="", flush=True)
print()

​
With Custom Tools

Pass tools to provide tool definitions for this request.

{
  "content": "What's the weather in SF?",
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get current weather",
        "parameters": {
          "type": "object",
          "properties": {
            "location": { "type": "string" }
          },
          "required": ["location"]
        }
      }
    }
  ]
}

When the model invokes a tool, the response has status: "REQUIRES_ACTION" with tool_calls. Submit the outputs via Submit Tool Outputs.

​
Request Body

FieldTypeRequiredDefaultDescription
contentstringYes—Text content of the message
thread_iduuidNo—Existing thread. Omit to auto-create
assistant_iduuidNo—Pin new thread to this assistant (shares memory, documents, config)
system_promptstringNo—Instructions for this request; falls back to the assistant’s stored description if omitted
llm_providerstringNoopenaiLLM provider
model_namestringNogpt-4oModel name
image_generationstringNooffauto enables built-in image tool; off disables it
image_model_providerstringNo—Required when image_generation=auto
image_model_namestringNo—Required when image_generation=auto
image_configobjectNo—Caller-fixed image controls supported by the selected model
video_generationstringNooffauto enables the video tool
video_model_providerstringNo—openrouter when video generation is enabled
video_model_namestringNo—Required when video generation is enabled
video_configobjectNo—Caller-fixed video controls supported by the selected model
streambooleanNofalseStream response as SSE
toolsarrayNo—Tool definitions for this request (OpenAI-style)
thinkingobjectNo—Reasoning controls
memorystringNooffMemory Lite: Auto, Readonly, off
memory_prostringNo—Memory Pro: Auto, Readonly
memory_response_citationbooleanNofalseCite memories in reply
web_searchstringNooffAuto or off
json_outputbooleanNofalseRequest JSON output
send_to_llmstringNotruefalse to save without LLM response
metadataobjectNo—Arbitrary metadata

​
Response

Non-streaming responses include:

FieldDescription
thread_idThread UUID (auto-created or existing)
assistant_idAssistant UUID used
contentThe assistant’s reply
message_idUnique message identifier
statusCOMPLETED, REQUIRES_ACTION, or FAILED
tool_callsTool call requests (when REQUIRES_ACTION)
run_idRun identifier
model_provider / model_nameModel used
input_tokens / output_tokens / total_tokensToken usage
retrieved_memoriesMemories used as context
retrieved_files / retrieved_files_countDocuments used as context
reasoningModel reasoning trace (when thinking is enabled)
context_usageContext window utilization

​
Image generation

Set image_generation to auto and pass image_model_provider and image_model_name to enable the built-in generate_image tool. Browse models with List Image Models. See Image Tool.

​
Authorizations

X-API-Key
required
string
API Key authentication

​
Query Parameters

authorization
x_session_token

​
Body

application/json
thread_id
string

Existing thread UUID. Omit to auto-create a new thread.

assistant_id
string

Assistant UUID to use. Omit to use the user's first assistant (auto-created if needed).

content
string

Text content of the message.

system_prompt
string

Instructions for this turn. Must be re-passed every call; not persisted. Falls back to the assistant's stored description if omitted.

llm_provider
string

LLM provider name (e.g. openai, anthropic, google). Default: openai.

model_name
string

Model name (e.g. gpt-4o, claude-sonnet-4-20250514). Default: gpt-4o.

image_generation
string

Image generation: 'auto' enables generate_image (requires image_model_provider and image_model_name); 'off' disables it.

image_model_provider
string

Required when image_generation=auto. Provider for generate_image (e.g. openrouter).

image_model_name
string

Required when image_generation=auto. Model for generate_image (e.g. google/gemini-2.5-flash-image).

stream
boolean

Whether to stream the AI response via SSE.

thinking
object

Flat reasoning controls inferred from the selected llm_provider/model. Use {} to enable provider defaults, or send only the fields supported by the selected model.

tools
array

Tool definitions for this turn (OpenAI-style). Must be re-passed every call; not persisted.

memory
string

Memory Lite mode: 'Auto', 'Readonly', or 'off'.

memory_response_citation
boolean

Whether the assistant should cite retrieved memories.

memory_citation
boolean

Deprecated alias for memory_response_citation.

memory_pro
string

Memory Pro mode: 'Auto', 'Readonly', or omit.

web_search
string

Web search mode: 'Auto' or 'off'.

send_to_llm
string

Whether to send to LLM for a response.

json_output
boolean

When true, request JSON object output from the model.

custom_timestamp
string

Custom timestamp for the message (merged into metadata for storage).

metadata
string

Optional metadata as JSON string or object.

voice
object

Optional voice config. Add stt for speech-to-text (requires multipart + audio_file); add tts for text-to-speech.

video_generation
string
video_model_provider
string

Required when video_generation=auto; openrouter is supported.

video_model_name
string

Video model ID from /models/video/all.

video_config
object

VideoConfig

image_config
object

ImageConfig

operation
string

Direct generation bypasses the chat model; use the matching image/video model and config fields.

system_one
object

SystemOneConfig

​
Response

application/json
  • 200

  • 422

Successful Response

message
required
string

Message

thread_id
required
string

Thread Id

timestamp
required
string

Timestamp

assistant_id
string | null

Assistant Id

content
string | null

Content

message_id
string | null

Message Id

role
string | null
status
string | null
tool_calls
array | null

Tool Calls

run_id
string | null

Run Id

memory_operation_id
string | null

Memory Operation Id

retrieved_memories
array | null
retrieved_files
array | null

Retrieved Files

retrieved_files_count
integer

Retrieved Files Count

reasoning
string | null

Reasoning

model_provider
string | null

Model Provider

model_name
string | null

Model Name

input_tokens
integer | null

Input Tokens

output_tokens
integer | null

Output Tokens

total_tokens
integer | null

Total Tokens

created_at
string | null

Created At

attachments
array | null
generated_media
array | null
voice_records
object | null

STT/TTS outcome: stt (transcript, input audio_url, usage) and/or tts (output audio_url, usage).

context_usage
object | null

Context Usage

system_one
object | null