Tools
Discover tools
input_schema, the JSON Schema forarguments.output_schema, the JSON Schema forstructured_content, ornullwhen the tool does not declare one.kind, which issync,async_submit, orjob_control.job_familyfor an asynchronous submit tool.cost_classandside_effect_levelwhen those classifications apply.
sync: the call returns atool_result.async_submit: the call returns202with atool_job.job_control: use the Jobs endpoints instead. Invoking these tools through REST returns400 use_job_endpoints.
ask_stefanbrain with a hosted video URL in the message.
Invoke a tool
arguments: an object that matches the tool’sinput_schema.chat: an optionalchat_...identifier where activity and artifacts should live.project: an optionalproj_...identifier or project UUID.
400 invalid_tool_arguments.
Without chat, StefanBrain reuses or creates the account’s Developer API chat. With project and no chat, it uses that project’s Developer API chat.
An inaccessible project returns 404 project_not_found. A chat that belongs to a different project returns 409 chat_project_mismatch.
Address submit tools by project and session
The seven asynchronous submit tools —create_images, edit_image, find_angles, get_meta_ad, research_shortform, review_copy, and review_funnel — also accept project and session inside arguments. A session label gives a workstream its own Developer API — <label> chat within the project.
Addressing precedence is:
Session labels use 1–128 characters from
A–Z, a–z, 0–9, _, ., :, or -.
Repeat the same project and session when polling through a client that resolves jobs by label. The REST acceptance URLs already carry the concrete chat query parameter.
Retry submit calls without duplicating work
SendIdempotency-Key on supported submit tools. A repeated key returns the original accepted job instead of starting or charging for another one.
ask_stefanbrain also accepts idempotency, with the same UTC-day window.
A tool-level provider or content failure can return HTTP
200 with is_error: true. Transport, authentication, validation, and limit failures use non-success status codes.chat_constraints, share_chat, request_connector_connect, collect_web_artifacts, knowledge_search, knowledge_read, generate_hooks, and find_marketing_angles (now find_angles) return 404 tool_not_available with a reason. manage_automations is in-app only and returns 404 tool_not_found, like an unknown tool name.
Retired (2026-09-22): create_skill, import_skill, and use_skill were removed from the Developer API. User-authored skills were retired; create_skill and import_skill no longer exist anywhere, and use_skill now only loads StefanBrain’s built-in reference files inside an agent run, so it returns 404 tool_not_found here. @stefanbrain/sdk and @stefanbrain/cli 0.3.0 drop the three tools from their generated types and catalog.
Call POST /api/developers/v1/files instead of invoking stage_file through REST, which returns 400 use_files_endpoint. The stage_file tool exists for MCP clients that cannot send a multipart HTTP request.
Likewise, use /api/developers/v1/feedback instead of invoking send_feedback or list_feedback through REST, which returns 400 use_feedback_endpoint. See Agent feedback.
Jobs
Handle an asynchronous job
Anasync_submit tool returns a job envelope similar to:
static_ad, cro_funnel_review, angle_finder, shortform_research, copy_chief, and meta_ad_lookup. Parked ask_stefanbrain answers poll under mcp_ask at GET /api/developers/v1/jobs/mcp_ask/{run_id}?chat={chat}.
Poll the status URL every 3–10 seconds until the top-level status is succeeded, failed, or cancelled, then fetch the result URL. data carries run_id, family, status, progress_message, progress, and error; the result call adds data.result. recommended_poll_after_ms is currently null.
Job status can be queued, running, succeeded, failed, or cancelled.
Status, result, and cancel calls return an object: "job" envelope:
statusis lifted to the top level for a stable polling loop.recommended_poll_after_msis the current delay hint, ornull.datacontains the family-specific status or result payload.contentpreserves the tool’s content blocks.is_errortells you whether the tool-level operation failed.errorcontains a typedcodeand readablemessagewhenis_erroristrue.
200 does not guarantee that the tool or job succeeded. Always check is_error, error, and the job’s terminal status.
Download job files
Jobs that produce files returndata.result.kind: "files" with a summary and each file’s workspace path. This holds in every chat, including a Developer API chat that has only taken tool calls. Static-ad jobs write one image and one .copy.md file per creative, plus an ad.json manifest and a brief.md when the run produced one.
To download them, list the job’s chat with GET /api/developers/v1/files?chat_id={chat}, match each path, and request that file’s download_url. A scoped key needs runs for these calls. See Files.
Inline results return data.result.kind: "inline" with summary and data.
See the generated REST reference for exact per-tool schemas. Use Agent Runs when StefanBrain should plan and complete a multi-step task.
