POST /v1/projects/{project}/workflows
Add a step to a project's custom workflow.
curl -X POST https://serpon.ai/v1/projects/1/workflows \
-H "Authorization: Bearer $SERPON_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"article_type": "product_datasheet",
"step_number": 1,
"step_name": "Research product details",
"step_description": "Compile specifications and use cases",
"system": "You are a technical writer specializing in product documentation.",
"user": "Research and compile detailed specifications for: {title}. Focus on features, specifications, and target use cases.",
"output_format": "json",
"timeout_seconds": 120,
"include_additional_context": true
}'
const res = await fetch('https://serpon.ai/v1/projects/1/workflows', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SERPON_TOKEN}`,
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify({
article_type: 'product_datasheet',
step_number: 1,
step_name: 'Research product details',
system: 'You are a technical writer specializing in product documentation.',
user: 'Research and compile detailed specifications for: {title}.',
output_format: 'json',
include_additional_context: true,
}),
});
const { data } = await res.json();
import os, requests
r = requests.post(
"https://serpon.ai/v1/projects/1/workflows",
headers={
"Authorization": f"Bearer {os.environ['SERPON_TOKEN']}",
"Accept": "application/json",
},
json={
"article_type": "product_datasheet",
"step_number": 1,
"step_name": "Research product details",
"system": "You are a technical writer specializing in product documentation.",
"user": "Research and compile detailed specifications for: {title}.",
"output_format": "json",
"include_additional_context": True,
},
)
data = r.json()["data"]
{
"success": true,
"data": {
"id": 501,
"workflow_id": 12,
"project_id": 1,
"article_type": "product_datasheet",
"step_number": 1,
"step_name": "Research product details",
"step_description": "Compile specifications and use cases",
"step_icon": null,
"system": "You are a technical writer specializing in product documentation.",
"user": "Research and compile detailed specifications for: {title}.",
"output_format": "json",
"timeout_seconds": 120,
"include_additional_context": true,
"include_additional_instruction": false,
"include_requirements": false,
"include_research": false,
"include_outline": false,
"json_schema": null,
"is_custom": true,
"is_redacted": false,
"created_at": "2026-08-02T11:00:00.000000Z",
"updated_at": "2026-08-02T11:00:00.000000Z"
}
}
{
"message": "The given data was invalid.",
"errors": {
"step_number": [
"A workflow step with this step number already exists for this article type in this project."
]
}
}
Create one step of a custom workflow.
POST https://serpon.ai/v1/projects/{project}/workflows
A workflow is built one step at a time: post step 1, then step 2, and so on. The first step you create for a given article_type creates the workflow itself, bringing that article type into existence for the project — after that, POST /v1/articles accepts it. See Custom workflows.
Authentication
Bearer token in the Authorization header. Requires update access to the project. See Authentication.
Path parameters
The project ID. Custom workflows are always scoped to one project.
Body parameters
Required
The custom type this step belongs to, max 255 characters. Cannot be one of the reserved built-in names (blog_post, ultimate_guide, listicle, product_review, comparison, tutorial, news, case_study, song_meaning, song_meaning_single_gpt_5).
Position in the pipeline, from 1. Must be unique within the workflow. Steps run in ascending order, and the numbers need not be contiguous.
Max 255 characters. Surfaced as current_step on articles while this step runs, so make it readable.
System prompt — the model's role and standing rules. Accepts template variables.
User prompt — the actual instruction for this step. Accepts template variables, including {step_N_output} to consume earlier steps.
text, json, or markdown. Use json for research and outline steps, markdown for steps that write prose.
Optional
Free-text note about what the step does. Shown in the dashboard.
Icon name for the dashboard, max 50 characters.
30–600. How long the step may run before it is treated as failed.
Structured-output schema, used with output_format: "json". Every object needs additionalProperties: false and a required list covering its properties; arrays need explicit items.
Inject the article's additional_context as {additional_context}. Best on research and planning steps.
Inject the article's additional_instruction as {additional_instruction}. Best on writing and revision steps.
Inject word count, tone, and point-of-view guidance as {requirements}. Belongs on the steps that actually write.
Inject web research results as {research}. A workflow must contain at least one step with this flag before articles of this type can set research_enabled.
Inject the generated outline as {outline}.
Example
Response fields
Always true on 201.
The created step. See Get workflow step for the full field reference.
Errors
| Status | When |
|---|---|
401 | Missing, invalid, or expired token |
402 | Account has no active subscription |
403 | No update access to the project |
404 | No such project |
422 | Reserved article type name, duplicate step_number, or a missing required field |
429 | Rate limit exceeded |
See Errors for the full reference.
Tips
Building a pipeline from nothing is slower than starting from a copy. Duplicate a type whose shape is close to what you want, then edit the steps.
Whatever the last step returns becomes the article's content. End the pipeline with a step that emits the finished body, not one that critiques it.