Skip to main content
POST
Create an article (draft) from a pre-built outline
Create a draft article. This does not generate body content - for a fully AI-written article in one step, use Generate Article. Use this when you already have an outline from Generate Outline and want manual control. Pass the outline under articleOutline, then call Start Generation with the returned slug to write the content. Required body fields: title, topicId, and articleOutline. articleOutline.generateOutlineResponse is optional: pass the whole object returned by Generate Outline to keep your reviewed outline, or omit it and the outline is planned during generation. A supplied generateOutlineResponse that is malformed (no outline in it) returns 400. Optional: type (listicle default, comparison, news, review, guide), content, status, contentArticleType (pillar or cluster), authors (names to credit in byline order, primary first; names of AI assistants or models, such as “Snowy” or “ChatGPT”, are dropped), keywords and prompts (each item { keyword | prompt, type: "primary" | "secondary" }; mark one keyword and one prompt primary, and any extra primaries are stored as secondary), metaData, internalLinkTargetSlugs, internalLinkTargetUrls, and language. Returns 201 with { article: { slug, teamId, title, status, type } }. Limited to 30 requests per minute.
A valid topicId is required - every article belongs to a topic cluster. Use Topics to find one, or Create Topic to add one. The topic name is taken from the cluster.
The optional language field sets the language code the article is written in (e.g. es). Codes are usually two letters, with three exceptions: Chinese is zh_CN or zh_TW, and Hebrew is iw (the legacy code, not he). Omit it to use your brand’s Writing Language (Settings → Content & CMS → Articles), falling back to your brand’s default language. Whichever applies is recorded on the article, so later refreshes, audits, and editor commands stay in that language even if the brand setting changes.

Authorizations

Authorization
string
header
required

Your SnowSEO API key (sk_...).

Body

application/json
title
string
required

Article title.

topicId
string
required

Required. Id of the team's topic cluster this article belongs to - get it from topic_clusters_list, or create one with create_topic_cluster. The topic name is taken from this cluster (do not pass a free-text topic).

articleOutline
object
required

Outline wrapper consumed by the generator. Shape: { generateOutlineResponse: , outlineAdditionalElements: { targetWordCount:number, _shouldIncludeFAQ:boolean, _shouldIncludeTldr:boolean, _shouldIncludeConclusion:boolean, _shouldIncludeCTA:boolean }, outlineNonEditable: { introduction: { estimated_words:150 }, conclusion?: { estimated_words:150 } }, audience_level:'auto', content_tone?:string }. Do NOT hand-author the outline - obtain it from generate_outline and pass it through unchanged.

teamId
string

Team id (falls back to the session's active project).

content
string

Optional markdown body. Leave empty for a draft you will fill via start_article_generation.

type
enum<string>
default:listicle

Article type. Defaults to listicle. Must match the outline's structure.

Available options:
listicle,
comparison,
news,
review,
guide
status
enum<string>
default:draft
Available options:
draft,
processing,
generated,
scheduled,
published,
failed,
manual
contentArticleType
string | null

"pillar" or "cluster" for pillar/cluster content, null/omitted for generic posts.

authors
string[]

Names to credit in the byline (real people or the user's brand), primary first. Omitted, the brand's default authors are used. Names of AI assistants or models (e.g. Snowy, ChatGPT) are dropped.

keywords
object[]

STRONGLY RECOMMENDED: the keywords from generate_keywords. Optional only because a user can legitimately deselect them all in the UI wizard - an agent should always pass them, since they are what the generated body targets. Mark exactly one as primary (the main search term the article targets) and the rest secondary; extra primaries are stored as secondary.

prompts
object[]

STRONGLY RECOMMENDED: the prompts from generate_prompts. Optional for the same reason as keywords; pass them so the article answers the questions it is meant to rank for. Mark exactly one as primary; extra primaries are stored as secondary.

metaData
object

Slugs of existing SnowSEO articles to link out to (internal links).

Absolute http(s) URLs to link out to that are not SnowSEO articles.

language
string

Language code to write this article in (e.g. 'es'). Usually two letters; Chinese is 'zh_CN'/'zh_TW' and Hebrew is 'iw'. Defaults to the brand's Writing Language, then its brand language. Only pass this when the user asks for a specific language for this one article.

Response

Default Response

article
object