POST /v1/articles
Create an article and start AI generation. Returns immediately with a queued article.
curl -X POST https://serpon.ai/v1/articles \
-H "Authorization: Bearer $SERPON_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"project_id": 1,
"title": "10 Best SEO Strategies for 2026",
"article_type": "listicle",
"target_word_count": 1500,
"tone": "professional",
"point_of_view": "second_person",
"language": "en",
"target_keyword": "SEO strategies 2026",
"keywords": "search engine optimization, organic traffic",
"country_targeting": "US",
"research_enabled": true,
"research_max_sources": 8,
"webhook_url": "https://example.com/hooks/serpon"
}'
const res = await fetch('https://serpon.ai/v1/articles', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SERPON_TOKEN}`,
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify({
project_id: 1,
title: '10 Best SEO Strategies for 2026',
article_type: 'listicle',
target_word_count: 1500,
tone: 'professional',
point_of_view: 'second_person',
language: 'en',
target_keyword: 'SEO strategies 2026',
keywords: 'search engine optimization, organic traffic',
country_targeting: 'US',
research_enabled: true,
research_max_sources: 8,
webhook_url: 'https://example.com/hooks/serpon',
}),
});
const { data } = await res.json();
import os, requests
r = requests.post(
"https://serpon.ai/v1/articles",
headers={
"Authorization": f"Bearer {os.environ['SERPON_TOKEN']}",
"Accept": "application/json",
},
json={
"project_id": 1,
"title": "10 Best SEO Strategies for 2026",
"article_type": "listicle",
"target_word_count": 1500,
"tone": "professional",
"point_of_view": "second_person",
"language": "en",
"target_keyword": "SEO strategies 2026",
"keywords": "search engine optimization, organic traffic",
"country_targeting": "US",
"research_enabled": True,
"research_max_sources": 8,
"webhook_url": "https://example.com/hooks/serpon",
},
)
data = r.json()["data"]
{
"success": true,
"message": "Article created successfully! AI content generation has started.",
"data": {
"id": 123,
"external_id": "550e8400-e29b-41d4-a716-446655440000",
"title": "10 Best SEO Strategies for 2026",
"description": null,
"content": null,
"original_content": null,
"current_version_id": null,
"published_version_id": null,
"status": "queued",
"article_type": "listicle",
"target_keyword": "SEO strategies 2026",
"keywords": ["search engine optimization", "organic traffic"],
"target_word_count": 1500,
"actual_word_count": 0,
"tone": "professional",
"point_of_view": "second_person",
"language": "en",
"country_targeting": "US",
"ai_model_used": null,
"cost": "0.00",
"current_step": null,
"humanize": false,
"ai_detection_score": null,
"originality_checked_at": null,
"additional_context": null,
"webhook_url": "https://example.com/hooks/serpon",
"project": { "id": 1, "name": "My SEO Blog" },
"created_at": "2026-08-02T10:30:00.000000Z",
"updated_at": "2026-08-02T10:30:00.000000Z"
}
}
{
"message": "The given data was invalid.",
"errors": {
"target_word_count": [
"Insufficient word quota. You have 500 words remaining this month. This article would require approximately 1800 words. Please reduce the target word count or upgrade your plan."
]
}
}
{
"error": "No active subscription",
"message": "This account has no active subscription. Subscribe to a plan to access the API.",
"code": "NO_ACTIVE_SUBSCRIPTION"
}
Create an article and start generating it.
POST https://serpon.ai/v1/articles
The response arrives as soon as the job is queued — generation itself takes minutes. Supply a webhook_url to be notified on completion, or poll GET /v1/articles/{id}. See Article lifecycle.
Authentication
Bearer token in the Authorization header. See Authentication.
Cost
Creation reserves 120% of target_word_count against the account's monthly word allowance and fails with 422 if it does not fit. The allowance is then spent against the words actually generated. See Rate limits & quotas.
Body parameters
Required
The project the article belongs to. Must be a project on an account you can access.
3–255 characters. Also available to prompts as {title}.
A built-in type, or a custom workflow type defined in this project. Determines which pipeline runs.
Built-in: blog_post, ultimate_guide, listicle, product_review, comparison, tutorial, news, case_study, song_meaning, song_meaning_single_gpt_5.
100–10,000. A target, not a guarantee — revision steps trim toward it.
professional, authoritative, friendly, conversational, casual, excited, or humorous. Also sets the generation temperature: the formal tones run cooler, the expressive ones hotter.
first_person, first_person_plural, second_person, or third_person.
en, es, fr, de, it, pt, ru, ja, ko, or zh.
SEO and targeting
Primary keyword, max 255 characters. Used throughout the prompts and as the search query when research is enabled.
Secondary keywords, either as a comma-separated string or an array. Up to 15 keywords, each max 80 characters. Always returned as an array. Woven into the article naturally where they fit.
US, GB, CA, AU, DE, FR, ES, IT, BR, or MX. Adds regional context and localises examples.
Who the article is for, max 1,000 characters. Omit the field to inherit the project's default audience; send null to write without one.
Generation control
Model identifier, e.g. gpt-5.4, gpt-4.1-mini, claude-sonnet-4-6. Must be an active model. Defaults to the cheapest active model.
A brand voice belonging to the same project. Applies its stored style rules to the writing.
Background material — product facts, notes, source text — max 25,000 characters. Reaches the steps with include_additional_context. The most effective single lever on output quality.
Directives about structure or style, max 2,000 characters. Reaches the steps with include_additional_instruction.
Run a humanization pass after generation and store it as a new version. Delays the completion webhook until the pass finishes.
Open the article with a bulleted "Key takeaways" summary, placed just after the introduction. Defaults to false.
Close the article with a "Frequently Asked Questions" section of 4-6 questions, placed after the conclusion. When a fresh SERP analysis exists for the target keyword, real searcher questions are preferred. Improves AI search coverage. Defaults to false.
title or sentence. Omit to leave heading capitalization to the model.
Submit through the provider's batch queue: about half the cost, up to 24 hours to return. Only valid for single-step workflows on a batch-enabled model — anything else is rejected. The article starts in batching rather than queued.
Overrides the initial status. Rarely useful — leave it unset and let the pipeline manage it.
Research
Search the web and feed extracted sources into the steps with include_research. Only valid for article types whose workflow contains such a step.
Up to 50 domains. When set, research uses only these, and the blocklist is ignored.
Up to 50 domains to exclude. Defaults to youtube.com, twitter.com, facebook.com, genius.com.
1–20. How many URLs to extract content from. Default 5.
50–5,000. Pages shorter than this are discarded as thin. Default 100.
100–10,000, and must be greater than or equal to research_min_content_words. Longer sources are truncated. Default 1000.
Images
0–5 images to generate for the article.
1:1, 16:9, 9:16, 3:4, or 4:3.
An image preset to apply a consistent visual style.
Delivery
Valid URL, max 500 characters. Receives a POST with the finished article when the status reaches completed. Three attempts, backing off 10s → 20s → 30s. See Article lifecycle.
Example
Response fields
Always true on 201.
Confirmation that generation has started.
The created article. See Get article for the full field reference. At creation, content, ai_model_used, and current_step are all null — they fill in as the pipeline runs.
Errors
| Status | When |
|---|---|
401 | Missing, invalid, or expired token |
402 | Account has no active subscription |
403 | No access to the requested project |
422 | Validation failed, or the monthly word quota cannot cover the article |
429 | Rate limit exceeded |
See Errors for the full reference.
Tips
additional_context moves output quality more than any other field. Real product facts, source notes, or a competitor's article pasted in beats any amount of prompt tuning.
Set target_word_count about 10–20% above the length you actually want. The revision steps trim, and a target set exactly at the goal tends to land under it.