create_content
Create a content document from an AI prompt, your own supplied text, or a blueprint template. It automatically pulls in all relevant brand and reference context, so there is no need to fetch context first. When generating from `instructions`, you can also pass `reference_content_ids` to fold specific existing documents into the prompt as reference material. The document's title always comes from its first heading — there is no title parameter.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
instructions | string | No | — | AI prompt describing what to create. Mutually exclusive with `content`. Required if `content` is omitted. If the user wants a specific document title, state it in this text — the title is taken from the generated document's first heading. |
content | string | No | — | Pre-written text to save directly as a document (no AI generation). Mutually exclusive with `instructions` — never send both, not even to carry a title — and cannot be combined with `blueprint_uuid`. Prefer markdown-formatted content. Start with the title as a level-1 heading (`# <Title>` on the first line): the document title is taken from the first heading. Use a markdown conversion tool first if you have a url or html. |
blueprint_uuid | string (uuid) | No | — | UUID of a blueprint to generate from (get from list_blueprints). When set, this becomes an ASYNC call — poll get_generation_status with the returned generation_id. Only valid with `instructions`. |
collection_ids | array of integers | No | — | Optional context collection IDs (from list_context_collections) to include during generation, on top of the always-on Brand Foundation + Reference Library + Project Context. |
dimension_option_ids | array of integers | No | — | Optional targeting dimension OPTION IDs (from list_targeting_dimensions — drill into each dimension's options) to shape the generation for a specific audience (e.g. persona, industry, buying stage). |
category_id | integer | No | — | Optional content category id from list_content_categories. Organizational only — does not change generation behavior. |
use_extended_thinking | boolean | No | false | Set true for complex content that benefits from deeper reasoning. Only applies to the freeform sync path (`instructions` without `blueprint_uuid`). |
project_id | string (uuid) | No | — | Optional project UUID (from list_projects) to associate the new content with. When set, the project's Project Context (brief + project context items) is automatically included in generation. |
plan_id | string | No | — | Optional plan UUID (from create_plan / list_plans / get_plan — use plan_uuid, not the integer id). Associates the new content with the plan and triggers an automatic stage transition to In_Process. Linkage applies only when used WITH blueprint_uuid (the async blueprint-generation path); sync paths accept the field without error but do not auto-link. Invalid plan_id is logged but does NOT fail content creation. Do NOT pass if the plan is in Complete stage — call update_plan target_stage='Accepted' first. |
reference_content_ids | array of string | No | — | Optional content UUIDs (from list_content, or list_content with `search`) whose full text is folded into the generation prompt as reference material. The canonical way to have Marcora write with reference to existing documents — no need to paste their text into `instructions`. Valid only on the generation paths (`instructions`, with or without `blueprint_uuid`); rejected with the verbatim `content` path. An unknown or inaccessible id fails the whole call (never silently skipped). |
Input Schema
{
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "Pre-written text to save directly as a document (no AI generation). Mutually exclusive with `instructions` — never send both, not even to carry a title — and cannot be combined with `blueprint_uuid`. Prefer markdown-formatted content. Start with the title as a level-1 heading (`# <Title>` on the first line): the document title is taken from the first heading. Use a markdown conversion tool first if you have a url or html."
},
"plan_id": {
"type": "string",
"format": "uuid",
"description": "Optional plan UUID (from create_plan / list_plans / get_plan — use plan_uuid, not the integer id). Associates the new content with the plan and triggers an automatic stage transition to In_Process. Linkage applies only when used WITH blueprint_uuid (the async blueprint-generation path); sync paths accept the field without error but do not auto-link. Invalid plan_id is logged but does NOT fail content creation. Do NOT pass if the plan is in Complete stage — call update_plan target_stage='Accepted' first."
},
"project_id": {
"type": "string",
"format": "uuid",
"description": "Optional project UUID (from list_projects) to associate the new content with. When set, the project's Project Context (brief + project context items) is automatically included in generation."
},
"category_id": {
"type": "integer",
"description": "Optional content category id from list_content_categories. Organizational only — does not change generation behavior."
},
"instructions": {
"type": "string",
"description": "AI prompt describing what to create. Mutually exclusive with `content`. Required if `content` is omitted. If the user wants a specific document title, state it in this text — the title is taken from the generated document's first heading."
},
"blueprint_uuid": {
"type": "string",
"format": "uuid",
"description": "UUID of a blueprint to generate from (get from list_blueprints). When set, this becomes an ASYNC call — poll get_generation_status with the returned generation_id. Only valid with `instructions`."
},
"collection_ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "Optional context collection IDs (from list_context_collections) to include during generation, on top of the always-on Brand Foundation + Reference Library + Project Context."
},
"dimension_option_ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "Optional targeting dimension OPTION IDs (from list_targeting_dimensions — drill into each dimension's options) to shape the generation for a specific audience (e.g. persona, industry, buying stage)."
},
"reference_content_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Optional content UUIDs (from list_content, or list_content with `search`) whose full text is folded into the generation prompt as reference material. The canonical way to have Marcora write with reference to existing documents — no need to paste their text into `instructions`. Valid only on the generation paths (`instructions`, with or without `blueprint_uuid`); rejected with the verbatim `content` path. An unknown or inaccessible id fails the whole call (never silently skipped)."
},
"use_extended_thinking": {
"type": "boolean",
"description": "Set true for complex content that benefits from deeper reasoning. Only applies to the freeform sync path (`instructions` without `blueprint_uuid`)."
}
}
}Output Schema
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "Content record ID (only present without blueprint)."
},
"title": {
"type": "string",
"description": "Document title (only present without blueprint)."
},
"content": {
"type": "string",
"description": "Document content in markdown (only present without blueprint)."
},
"link_url": {
"type": "string",
"format": "uri",
"description": "Direct URL to view/open this content in Marcora (only present without blueprint)."
},
"content_id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier — use as content_id in get_content and share tools (only present without blueprint)."
},
"created_at": {
"type": "integer",
"description": "Unix timestamp of creation (only present without blueprint)."
},
"generation_id": {
"type": "string",
"format": "uuid",
"description": "UUID to track async generation — pass to get_generation_status to poll for completion (only present WITH blueprint)."
}
},
"description": "When blueprint_uuid is NOT provided, returns the content object directly. When blueprint_uuid IS provided, returns only generation_id — poll get_generation_status to track progress."
}Instructions
Use this tool to create content. You can create content from scratch using an AI prompt, supply your own content directly, or generate from a blueprint.
Document title — there is no title parameter. A document's title is always taken from its first heading, and it keeps following that heading when the document is edited later. So put the title IN the document:
- With
content: start the markdown with the title as a level-1 heading on the first line —# <Title>— then the body. - With
instructions: if the user wants a specific title, say so in the instructions text (e.g. "Title it: Weekly Trends – Sept 16"). Marcora writes it as the document's first heading. - Never pass both
contentandinstructions— not even to carry a title. Pick one path; a call with both is rejected.
Revising an existing document? Use update_content instead — edit it in place rather than forking a new doc. Edits are non-destructive: Marcora keeps a version history and the user can revert from the app.
Context handling depends on which input you use — this matters:
instructions(Marcora writes it): this tool internally pulls all relevant context — Brand Foundation + Reference Library (relevancy-scored) + Project Context (ifproject_idis set) + any Context Collections you pass incollection_ids. Do NOT pre-fetch withget_relevant_context— that's wasted work. Just pass any explicit collection_ids / dimension_option_ids you want included and let this tool gather everything else.content(you supply finished text): this tool stores your markdown VERBATIM and consults NO context — not Brand Foundation, not the Reference Library, not Project Context. If YOU are composing the content yourself, callget_relevant_contextwithinclude_brand_foundation: trueFIRST and write from what it returns; otherwise your draft ignores the team's brand and reference material.
Referencing existing content — use reference_content_ids: to have Marcora generate WITH REFERENCE to existing documents (a past post to echo, a brief to build on), pass their content UUIDs (from list_content, or list_content with search) in reference_content_ids. The tool resolves each id server-side, pulls its full text, and folds it into the generation prompt as reference material. THIS is the canonical way to include existing content — you no longer need to paste document text into instructions. Valid only on the generation paths (instructions, with or without blueprint_uuid); it is REJECTED with the verbatim content path, which consults no context. Unknown or inaccessible ids fail loud (the whole call errors), so pass ids you got from a list/get tool.
Choosing a path for net-new content: to get something written against the team's full context automatically, prefer instructions and let Marcora generate it. Use content to save text the user already wrote or approved — or when the user specifically wants YOU (the AI agent) to do the writing, in which case ground yourself with get_relevant_context first (see above).
With content (synchronous):
Creates a document with your supplied markdown-formatted content directly — no AI generation. SYNCHRONOUS — returns the content object immediately.
With instructions (no blueprint_uuid) (synchronous):
Creates a freeform document from an AI prompt. SYNCHRONOUS — typically takes 1-3 minutes. Returns the content object directly.
With instructions + blueprint_uuid (asynchronous):
Generates content from a blueprint template. ASYNC — returns a generation_id immediately. You must then poll get_generation_status with the generation_id until the status is "completed". This typically takes 3-5 minutes.
You must provide either 'content' or 'instructions' (not both). The 'content' parameter cannot be used with blueprint_uuid.
Workflow:
- Provide 'content' to save your own text directly as a document.
- OR provide 'instructions' describing what to create (AI will generate it).
- Optionally provide blueprint_uuid from list_blueprints to generate from a template (instructions only).
- Optionally get category_id from list_content_categories.
- Optionally get dimension_option_ids from list_targeting_dimensions.
- Optionally get collection_ids from list_context_collections.
- Set use_extended_thinking=true for complex content (only applies with instructions, without blueprint).
- Optionally provide reference_content_ids (content UUIDs from list_content) to fold existing content into the generation as reference material (instructions paths only).
PLAN INTEGRATION (additive — existing behavior unchanged):
- When the user has an active plan they want to fulfill, pass
plan_idwith the plan's UUID. The content will be linked to the plan and the plan will transition to In_Process automatically. - plan_id is purely associative: the endpoint does NOT look up plan parameters server-side. Use
get_planto read prompt, blueprint_id, project_id, collection IDs, and targeting dimension IDs from the plan, then pass them explicitly here alongside plan_id. - Do NOT pass plan_id if the plan is in Complete stage. Call
get_planfirst to verify the current stage. If Complete, callupdate_planwith target_stage='Accepted' to re-open it — confirm with the user — then call create_content. - Linkage scope: plan_id triggers automatic plan↔content linking ONLY when used with
blueprint_uuid(the async blueprint-generation path). The synchronous paths (directcontent, orinstructionswithoutblueprint_uuid) acceptplan_idwithout error but do NOT currently establish the link automatically. For the standard plan-fulfillment flow, passblueprint_uuidfrom the plan. - Invalid plan_id is non-fatal: an invalid plan_id (not found, wrong format) is logged but content creation SUCCEEDS.
Links: present link_url to the user exactly as returned — copy it character for character. Never retype, shorten, or rebuild a link or the IDs inside it.
Examples
Save direct content (sync)
Supply your own text directly as a document — no AI generation. SYNCHRONOUS — returns immediately.
{
"content": "# Product Update Q2 2026\n\nWe shipped three major features this quarter...\n\n## SSO Integration\n\nEnterprise customers can now sign in with their existing identity provider.",
"category_id": 5,
"project_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}{
"id": 1235,
"content_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "Product Update Q2 2026",
"content": "# Product Update Q2 2026\n\nWe shipped three major features this quarter...\n\n## SSO Integration\n\nEnterprise customers can now sign in with their existing identity provider.",
"created_at": 1712678400,
"link_url": "https://app.marcora.ai/canvas/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}Generate content from a blueprint (async)
Use a blueprint template with context collections and targeting dimensions. This is ASYNCHRONOUS — returns a generation_id immediately. Poll get_generation_status with the generation_id until status is completed.
{
"instructions": "Write a blog post about our new enterprise SSO feature. Focus on security benefits and ease of setup.",
"blueprint_uuid": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"category_id": 5,
"collection_ids": [3, 7],
"dimension_option_ids": [12, 45],
"project_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}{
"generation_id": "7c9e6a2b-1f4d-4a8e-b3c5-9d2e1f6a4b8c"
}Quick content from AI prompt (sync)
Generate content from instructions without a blueprint. This is SYNCHRONOUS — returns the full content object directly (typically 1-3 minutes). No need to poll get_generation_status.
{
"instructions": "Write a short LinkedIn post announcing our Series B funding. Keep it under 200 words, celebratory but professional."
}{
"id": 1234,
"content_id": "e5f6a7b8-c9d0-1234-ef01-234567890abc",
"title": "We just closed our Series B!",
"content": "# We just closed our Series B!\n\nThrilled to announce...",
"created_at": 1712678400,
"link_url": "https://app.marcora.ai/canvas/e5f6a7b8-c9d0-1234-ef01-234567890abc"
}