Writer Concepts
Writer profiles are collections of configuration fields that control how the AI writes. Most fields are optional -- start with just a name and a style guide, then add configuration as you identify what to refine. See the Quickstart to create your first writer and run a job.
Configuration Strategy
Most writers do not need every field. Here is a practical progression:
-
Start minimal -- create a writer with just
nameandstyleGuide. Run a few jobs and review the output. -
Add guardrails -- as you identify patterns to eliminate, add them to
bannedLanguageandconstitution. -
Tune quality -- adjust
evaluationDimensions,qualityThreshold, andmaxEditPassesbased on how quality vs. speed matters for your use case. -
Use structured output -- when you need machine-readable output or consistent schema across all jobs, add
structuredOutputSchema. -
Use overrides for variation -- rather than creating many similar writer profiles, use
overridesin the job request to handle per-job differences.
For highest-quality output, combine:
{
"qualityThreshold": 0.9,
"maxEditPasses": 10,
"evaluationDimensions": [
"brand voice consistency",
"factual accuracy",
"persuasiveness",
"clarity",
"completeness"
]
}
This configuration will iterate more aggressively before completing a job. Expect higher latency in exchange for better results.
Core Identity
name
Type: string | Required | Max: 256 characters
Human-readable label for the writer. Must be unique within your organization. The name is used to identify the writer in the API and dashboard -- it is not passed to the AI agent as part of the writing context.
{
"name": "B2B SaaS Blog Writer"
}
description
Type: string | Optional | Max: 2,000 characters
A description of the writer's purpose. Unlike name, this is passed to the AI agent and provides context about what this writer is for, which can improve output consistency.
{
"description": "Writes long-form blog posts for a B2B SaaS audience. Topics include product updates, engineering deep-dives, and thought leadership. Assumes readers are technically literate."
}
Voice & Style
styleGuide
Type: string | Optional | Max: 10,000 characters
Free-text writing instructions for the AI. This is the primary mechanism for controlling voice and style. Write it the way you would brief a skilled human writer.
Effective style guides are specific, opinionated, and include examples of both what to do and what to avoid.
Examples of effective style guides:
{
"styleGuide": "Write in an authoritative but approachable tone. Use short sentences. Lead with the most important point. Avoid jargon unless the audience would expect it. Never use passive voice when active voice works."
}
{
"styleGuide": "Conversational and direct. Write like you are explaining to a smart friend, not presenting at a conference. Use contractions freely. Second person ('you') throughout. OK to use sentence fragments for emphasis."
}
{
"styleGuide": "Academic rigor with accessible language. Every claim needs a basis. Hedging language when appropriate ('research suggests', 'evidence indicates'). Formal but not stuffy -- no Latin phrases, no excessive nominalization."
}
toneMatrix
Type: object | Optional
Key-value pairs defining tone across specific dimensions. Complements styleGuide by providing structured, explicit tone controls. Where styleGuide is free-text narrative instruction, toneMatrix gives the AI named dimensions to reason against.
{
"toneMatrix": {
"formality": "casual",
"humor": "dry",
"technicality": "expert",
"enthusiasm": "measured",
"pov": "opinionated"
}
}
The keys and values are arbitrary -- use whatever dimensions make sense for your content. The AI interprets them as tone guidance alongside your styleGuide.
audienceProfile
Type: string | Optional | Max: 2,000 characters
A description of the target audience. Helps the AI calibrate assumed knowledge, vocabulary, and framing.
{
"audienceProfile": "Senior software engineers and engineering managers at companies with 50-500 employees. Familiar with distributed systems, CI/CD, and modern cloud infrastructure. Skeptical of vendor marketing. Value concrete benchmarks and real-world trade-offs over abstract claims."
}
{
"audienceProfile": "Small business owners considering their first CRM purchase. Non-technical. Primary concern is saving time and not losing leads. May be intimidated by software complexity. Decision is often made alone, without an IT team."
}
Content Guardrails
bannedLanguage
Type: string[] | Optional | Max: 100 items, 1,000 characters each | Default: []
Words and phrases the AI must not use. Applied strictly -- if a banned term appears in the output it will be revised out.
{
"bannedLanguage": [
"utilize",
"leverage",
"synergy",
"cutting-edge",
"game-changer",
"seamless",
"robust",
"best-in-class",
"paradigm shift"
]
}
Useful for enforcing brand voice consistency and eliminating overused filler language.
constitution
Type: string[] | Optional | Max: 100 items, 1,000 characters each | Default: []
Rules the AI must follow when writing. Each item is a discrete rule evaluated during quality passes. Think of this as a checklist the editor applies to every piece.
{
"constitution": [
"Never make unsubstantiated claims about competitor products",
"Always include a call-to-action in the final paragraph",
"Cite sources when making specific factual or statistical claims",
"Do not promise specific ROI or performance outcomes",
"Refer to the company as 'Acme' not 'Acme Inc.' or 'Acme Corporation'"
]
}
exampleBank
Type: string[] | Optional | Max: 100 items, 1,000 characters each | Default: []
Example texts that represent the voice and style you want. The AI uses these as reference material for voice matching. Longer, more representative examples work better than short snippets.
{
"exampleBank": [
"If you have ever spent an afternoon tracking down why a distributed trace shows 200ms of unexplained latency, you know the feeling. The profiler says the code is fast. The database says the queries are fast. But somewhere in the gap between services, time disappears. This post is about finding that time.",
"We shipped a breaking change last Tuesday. Not on purpose. Here is what happened, what we did about it, and the three process changes we made to ensure it does not happen again."
]
}
Structured Output
Structured output is a first-class capability that lets writers produce machine-readable JSON instead of plain text. This is useful for:
- Product catalogs -- generate title, description, and metadata in one pass
- Metadata extraction -- produce SEO fields, tags, and summaries alongside content
- Templated content -- enforce consistent schema across all output
- Downstream pipelines -- feed structured content directly into CMS or data systems
When structuredOutputSchema is set, the writer produces JSON conforming to that schema in the structuredContent field of the job response, rather than plain text in content.
structuredOutputSchema
Type: object (JSON Schema) | Optional
A JSON Schema object. The writer produces JSON that conforms to this schema. Standard JSON Schema Draft 7 features are supported.
Example -- create a writer with a product description schema:
curl -X POST https://api.feeds.onhelix.ai/writers \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Product Description Writer",
"styleGuide": "Concise and benefit-focused. Lead with what the customer gets, not what the product does. Use active voice.",
"audienceProfile": "Online shoppers comparing products. Scanning, not reading. Price-sensitive but quality-aware.",
"structuredOutputSchema": {
"type": "object",
"required": ["title", "tagline", "description", "features", "seoKeywords", "metaDescription"],
"properties": {
"title": {
"type": "string",
"description": "Product name, 60 characters or fewer"
},
"tagline": {
"type": "string",
"description": "One-sentence value proposition, 120 characters or fewer"
},
"description": {
"type": "string",
"description": "Full product description, 150-300 words"
},
"features": {
"type": "array",
"items": { "type": "string" },
"description": "3-5 key product features as short phrases"
},
"seoKeywords": {
"type": "array",
"items": { "type": "string" },
"description": "5-10 target SEO keywords"
},
"metaDescription": {
"type": "string",
"description": "Meta description for search results, 150-160 characters"
}
}
}
}'
Start a job using the structured writer:
curl -X POST https://api.feeds.onhelix.ai/writers/{writerId}/jobs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Write product content for a stainless steel insulated water bottle. 32oz capacity. Keeps drinks cold 24 hours, hot 12 hours. BPA-free. Comes in matte black, slate blue, and forest green. Retail price $45.",
"research": "Customer reviews highlight the tight-sealing lid and condensation-free exterior as top differentiators. Main competitors are Hydro Flask and YETI."
}'
Response:
{
"success": true,
"data": {
"status": "completed",
"structuredContent": {
"title": "32oz Insulated Stainless Steel Water Bottle",
"tagline": "Cold 24 hours, hot 12 hours -- without the sweat on the outside.",
"description": "Built for all-day hydration, this 32oz bottle keeps your drinks at the right temperature from morning coffee to afternoon ice water. The double-wall vacuum insulation eliminates condensation, so your bag stays dry and your grip stays sure. The BPA-free stainless steel construction is tough enough for daily carry and easy to clean. Available in matte black, slate blue, and forest green.",
"features": [
"Keeps drinks cold up to 24 hours, hot up to 12 hours",
"Condensation-free exterior -- no wet bag, no slipping",
"BPA-free 18/8 stainless steel",
"32oz capacity -- enough for the full day",
"Leak-proof lid tested to 50psi"
],
"seoKeywords": [
"insulated water bottle",
"stainless steel water bottle",
"32oz water bottle",
"hydro flask alternative",
"vacuum insulated bottle",
"BPA free water bottle",
"cold water bottle 24 hours"
],
"metaDescription": "32oz vacuum-insulated stainless steel water bottle. Keeps drinks cold 24h, hot 12h. BPA-free, condensation-free. $45. Free shipping."
},
"outline": { ... },
"metadata": { ... }
}
}
Notes on structured output:
styleGuide,toneMatrix, andconstitutionstill apply to text within the structured fields.formattingRulescontrols Markdown and document structure, which may not be relevant when producing JSON -- it will be ignored for structured fields unless your schema includes a field intended to contain formatted text.- When
structuredOutputSchemais not set, the writer produces plain text in thecontentfield of the job response.
Output Control
formattingRules
Type: string | Optional | Max: 5,000 characters
Instructions for document structure and formatting. Applied in addition to styleGuide.
{
"formattingRules": "Use Markdown. H2 for main sections, H3 for subsections. Use bullet lists for key points, numbered lists for sequential steps. Bold for key terms on first use. No tables unless the content is genuinely tabular."
}
contentBriefTemplate
Type: string | Optional | Max: 10,000 characters
A template that defines the expected structure of every piece produced by this writer. Useful for enforcing consistent document structure across high-volume output.
{
"contentBriefTemplate": "Introduction (1 paragraph -- hook and thesis)\nBackground (1-2 paragraphs -- context and why this matters)\nMain Points (3-5 sections, each with a clear subheading)\nPractical Implications (1 paragraph -- what readers should do with this)\nConclusion with call-to-action (1 paragraph)"
}
maxLength
Type: integer | Optional | Min: 1
Maximum word count for the output. The writer will not exceed this limit.
{
"maxLength": 1200
}
minLength
Type: integer | Optional | Min: 1
Minimum word count for the output. The writer will continue revising until this threshold is met.
{
"minLength": 600
}
minLength and maxLength can be used together to target a word count range. If both are provided, minLength must be less than or equal to maxLength.
Quality Control
qualityThreshold
Type: number | Optional | Range: 0.0 -- 1.0 | Default: 0.7
The minimum quality score the editor must assign before the job completes. If a pass scores below this threshold, the writer revises and tries again (up to maxEditPasses).
| Range | Use case |
|---|---|
| 0.5 -- 0.6 | Rough drafts, internal documents, high-volume low-stakes content |
| 0.7 -- 0.8 | Standard published content |
| 0.9+ | Polished output where quality matters more than speed |
{
"qualityThreshold": 0.85
}
maxEditPasses
Type: integer | Optional | Range: 1 -- 50 | Default: 3
Maximum number of edit iterations. Acts as a safety limit -- the job completes with the best result achieved so far if this limit is reached before the quality threshold is met. Set higher for quality-sensitive content where you are willing to wait.
{
"maxEditPasses": 8
}
evaluationDimensions
Type: string[] | Optional | Max: 100 items, 1,000 characters each | Default: ["clarity", "completeness", "tone", "coherence", "accuracy"]
The criteria the editor uses when scoring each pass. Customize these to match what matters for your specific use case.
{
"evaluationDimensions": [
"brand voice consistency",
"SEO keyword density and placement",
"readability at an 8th grade level",
"call-to-action strength",
"factual accuracy"
]
}
The default dimensions cover broad writing quality. Override them when your use case has specific, measurable requirements the default dimensions would not capture.
Behavior Flags
humanize
Type: boolean | Optional | Default: true
When true, the output is post-processed to reduce patterns commonly associated with AI-generated text -- overly uniform sentence rhythm, certain transitional phrases, and predictable structural choices. Set to false if this post-processing step is not needed for your use case (it adds latency).
{
"humanize": false
}
otherInstructions
Type: string | Optional | Max: 10,000 characters
A catch-all field for instructions that do not fit cleanly into other configuration fields. Passed directly to the AI agent.
{
"otherInstructions": "This writer is used for a newsletter that goes out every Tuesday. Assume readers have seen previous editions -- do not re-explain recurring concepts like our pricing model or company background. When referencing products, always include the version number if one is available in the prompt."
}
Per-Job Inputs
These fields are provided when starting a job, not when creating a writer. They allow per-job customization without modifying the writer profile.
prompt
Type: string | Required | Max: 100,000 characters
The writing instruction for this specific job. Describe what you want written.
{
"prompt": "Write a 900-word blog post explaining the difference between synchronous and asynchronous API design. Assume the reader is a backend developer who has worked with REST but has not thought deeply about the trade-offs."
}
research
Type: string | Optional | Max: 100,000 characters
Pre-gathered research or source material the writer should use. Can come from the Deep Research feature or any external source -- scraped web pages, internal documents, database exports, interview transcripts.
{
"research": "From internal data: average support ticket resolution time dropped from 4.2 days to 1.8 days after implementing the new triage system. NPS improved from 34 to 61 over the same period. The triage system was built by a team of two engineers over six weeks..."
}
toneContext
Type: string | Optional | Max: 10,000 characters
Per-job tone guidance that supplements the writer's toneMatrix. Use this when a specific job calls for a tone shift without changing the underlying writer profile.
{
"toneContext": "This post is in response to a service outage last week. Strike a balance between accountability and confidence. Acknowledge what went wrong plainly. Do not be defensive. End on a forward-looking note."
}
overrides
Type: object | Optional
Override any writer configuration field for this job only. The writer profile is not modified. Use this for one-off variation without creating separate writer profiles.
{
"overrides": {
"maxEditPasses": 5,
"qualityThreshold": 0.9,
"humanize": false,
"maxLength": 500
}
}
Any field that can be set on a writer can be overridden here.
jobId
Type: string | Optional | Max: 256 characters | Format: alphanumeric, hyphens, underscores
An idempotency key for the job. If a job with this ID already exists for this writer, the existing job is returned rather than starting a new one. If omitted, a UUID is generated automatically.
{
"jobId": "weekly-newsletter-2026-03-23"
}
Useful when you need to safely retry a job submission without risk of duplicate runs.
Next Steps
- API Reference -- full endpoint and parameter documentation
- Quickstart -- create a writer and run your first job
- Overview -- how the writer system works