POST /v1/projects/{project}/workflows/duplicate
Clone an entire workflow into a new custom article type.
curl -X POST https://serpon.ai/v1/projects/1/workflows/duplicate \
-H "Authorization: Bearer $SERPON_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"source_article_type": "blog_post",
"new_article_type": "product_datasheet"
}'
const res = await fetch('https://serpon.ai/v1/projects/1/workflows/duplicate', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SERPON_TOKEN}`,
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify({
source_article_type: 'blog_post',
new_article_type: 'product_datasheet',
}),
});
const { data } = await res.json();
import os, requests
r = requests.post(
"https://serpon.ai/v1/projects/1/workflows/duplicate",
headers={
"Authorization": f"Bearer {os.environ['SERPON_TOKEN']}",
"Accept": "application/json",
},
json={
"source_article_type": "blog_post",
"new_article_type": "product_datasheet",
},
)
workflow = r.json()["data"]
steps = workflow["steps"]
{
"success": true,
"data": {
"id": 13,
"project_id": 1,
"name": "Product Datasheet",
"slug": "product_datasheet",
"description": null,
"revision": 3,
"is_custom": true,
"steps": [
{
"id": 601,
"workflow_id": 13,
"project_id": 1,
"article_type": "product_datasheet",
"step_number": 1,
"step_name": "Research",
"system": "You are a research assistant. Research the topic thoroughly.",
"user": "Research the topic: {title}.",
"output_format": "json",
"is_custom": true,
"is_redacted": false,
"created_at": "2026-08-02T11:40:00.000000Z",
"updated_at": "2026-08-02T11:40:00.000000Z"
},
{
"id": 602,
"workflow_id": 13,
"project_id": 1,
"article_type": "product_datasheet",
"step_number": 2,
"step_name": "Outline",
"output_format": "json",
"is_custom": true,
"is_redacted": false,
"created_at": "2026-08-02T11:40:00.000000Z",
"updated_at": "2026-08-02T11:40:00.000000Z"
}
],
"created_at": "2026-08-02T11:40:00.000000Z",
"updated_at": "2026-08-02T11:40:00.000000Z"
}
}
{
"message": "The given data was invalid.",
"errors": {
"new_article_type": [
"A custom workflow with this article type already exists in this project."
]
}
}
Clone every step of an existing workflow into a new custom article type in this project.
POST https://serpon.ai/v1/projects/{project}/workflows/duplicate
This is the fastest way to start a custom workflow: copy a pipeline whose shape is close to what you want, then edit the copy. See Custom workflows.
Authentication
Bearer token in the Authorization header. Requires update access to the project. See Authentication.
What gets copied
Step structure, ordering, output formats, timeouts, context flags, and JSON schemas always transfer. Prompts depend on the source:
| Source | Prompts in the copy |
|---|---|
| One of your project's custom types | Copied verbatim |
A built-in type (blog_post, listicle, …) | Replaced with generic starter prompts |
Serpon's tuned production prompts are not extractable. Duplicating a built-in workflow gives you its pipeline shape with workable placeholder prompts — a starting point to rewrite, not a copy of the originals.
Path parameters
The project that receives the copy.
Body parameters
What to copy: a built-in type, or a custom type that already exists in this project. Max 255 characters. When a custom type of this name exists in the project, it wins over the built-in of the same name.
Name for the copy, max 255 characters. Cannot be a reserved built-in name, and cannot already exist in this project.
Example
Response fields
Always true on 201.
The workflow that was created, with every copied step nested under steps in order. Same shape as one entry from List workflows.
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 | Source type does not exist, target name is reserved, or it already exists in this project |
429 | Rate limit exceeded |
See Errors for the full reference.
After duplicating
The copy is live immediately — POST /v1/articles accepts the new article_type right away. Realistically you want to edit it first:
Read the copied steps
The response already contains them under steps, or list them filtered by article_type to fetch them again.
Rewrite the prompts
Update each step. Copies of built-in workflows especially need this — their prompts are deliberately generic.
Generate a test article
Run one article through the new type at a modest word count before pointing production traffic at it.