Skip to main content

API Reference

Complete reference for the Helix Writer API.

Base URL

https://api.feeds.onhelix.ai

Authentication

All requests require API key authentication using the Bearer token scheme:

Authorization: Bearer YOUR_API_KEY

See the Authentication Guide for details on obtaining and using API keys.

Create Writer

Create a new writer with a configured style, tone, and quality settings.

POST /writers

Request

Headers:

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Body:

{
"name": "Tech Blog Writer",
"description": "Writes technical blog posts for developers",
"styleGuide": "Use clear, direct language. Avoid jargon unless necessary.",
"toneMatrix": { "formality": "casual", "enthusiasm": "high" },
"audienceProfile": "Software engineers with 2-10 years of experience",
"maxLength": 2000,
"minLength": 500,
"humanize": true
}

Parameters:

ParameterTypeRequiredDescription
namestringYesWriter name (1--256 chars, unique per org)
descriptionstringNoWriter description (1--2,000 chars)
styleGuidestringNoWriting style instructions (1--10,000 chars)
toneMatrixobjectNoKey-value tone dimensions
exampleBankstring[]NoExample texts for style matching (max 100 items, 1,000 chars each)
bannedLanguagestring[]NoWords/phrases to avoid (max 100 items, 1,000 chars each)
constitutionstring[]NoRules the AI must follow (max 100 items, 1,000 chars each)
audienceProfilestringNoTarget audience description (1--2,000 chars)
maxLengthintegerNoMaximum word count (min 1)
minLengthintegerNoMinimum word count (min 1)
formattingRulesstringNoFormatting instructions (1--5,000 chars)
maxEditPassesintegerNoMax edit iterations (1--50, default: 3)
qualityThresholdnumberNoQuality score threshold (0--1, default: 0.7)
evaluationDimensionsstring[]NoQuality evaluation criteria (max 100 items, 1,000 chars each, default: see below)
structuredOutputSchemaobjectNoJSON schema for structured output
humanizebooleanNoRemove AI patterns (default: true)
otherInstructionsstringNoAdditional instructions (1--10,000 chars)
contentBriefTemplatestringNoContent structure template (1--10,000 chars)

The default evaluationDimensions are: ["clarity", "completeness", "tone", "coherence", "accuracy"].

Response

Status: 201 Created

{
"success": true,
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"organizationId": "org-uuid-here",
"name": "Tech Blog Writer",
"description": "Writes technical blog posts for developers",
"styleGuide": "Use clear, direct language. Avoid jargon unless necessary.",
"toneMatrix": { "formality": "casual", "enthusiasm": "high" },
"exampleBank": [],
"bannedLanguage": [],
"constitution": [],
"audienceProfile": "Software engineers with 2-10 years of experience",
"maxLength": 2000,
"minLength": 500,
"formattingRules": null,
"maxEditPasses": 3,
"qualityThreshold": 0.7,
"evaluationDimensions": [
"clarity",
"completeness",
"tone",
"coherence",
"accuracy"
],
"structuredOutputSchema": null,
"humanize": true,
"otherInstructions": null,
"contentBriefTemplate": null,
"createdAt": "2026-01-15T10:00:00.000Z",
"updatedAt": "2026-01-15T10:00:00.000Z",
"deletedAt": null
}
}

Response Fields:

FieldTypeDescription
idstringUnique writer identifier
organizationIdstringOrganization this writer belongs to
namestringWriter name
descriptionstring | nullWriter description
styleGuidestring | nullWriting style instructions
toneMatrixobject | nullKey-value tone dimensions
exampleBankstring[]Example texts for style matching
bannedLanguagestring[]Words/phrases to avoid
constitutionstring[]Rules the AI must follow
audienceProfilestring | nullTarget audience description
maxLengthinteger | nullMaximum word count
minLengthinteger | nullMinimum word count
formattingRulesstring | nullFormatting instructions
maxEditPassesintegerMax edit iterations
qualityThresholdnumberQuality score threshold
evaluationDimensionsstring[]Quality evaluation criteria
structuredOutputSchemaobject | nullJSON schema for structured output
humanizebooleanWhether AI pattern removal is enabled
otherInstructionsstring | nullAdditional instructions
contentBriefTemplatestring | nullContent structure template
createdAtstringISO 8601 creation timestamp
updatedAtstringISO 8601 last update timestamp
deletedAtstring | nullISO 8601 deletion timestamp, or null

Errors

400 Bad Request:

{
"success": false,
"error": "Validation error: name must be at least 1 character"
}
{
"success": false,
"error": "A writer with this name already exists in your organization"
}

401 Unauthorized:

{
"success": false,
"error": "Invalid or missing API key"
}

Example

curl -X POST https://api.feeds.onhelix.ai/writers \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Tech Blog Writer",
"description": "Writes technical blog posts for developers",
"styleGuide": "Use clear, direct language. Avoid jargon unless necessary.",
"audienceProfile": "Software engineers with 2-10 years of experience",
"maxLength": 2000,
"minLength": 500
}'

List Writers

Retrieve all writers for your organization.

GET /writers

Request

Headers:

Authorization: Bearer YOUR_API_KEY

Response

Status: 200 OK

{
"success": true,
"data": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"organizationId": "org-uuid-here",
"name": "Tech Blog Writer",
"description": "Writes technical blog posts for developers",
"styleGuide": "Use clear, direct language. Avoid jargon unless necessary.",
"toneMatrix": { "formality": "casual", "enthusiasm": "high" },
"exampleBank": [],
"bannedLanguage": [],
"constitution": [],
"audienceProfile": "Software engineers with 2-10 years of experience",
"maxLength": 2000,
"minLength": 500,
"formattingRules": null,
"maxEditPasses": 3,
"qualityThreshold": 0.7,
"evaluationDimensions": [
"clarity",
"completeness",
"tone",
"coherence",
"accuracy"
],
"structuredOutputSchema": null,
"humanize": true,
"otherInstructions": null,
"contentBriefTemplate": null,
"createdAt": "2026-01-15T10:00:00.000Z",
"updatedAt": "2026-01-15T10:00:00.000Z",
"deletedAt": null
}
]
}

Errors

401 Unauthorized:

{
"success": false,
"error": "Invalid or missing API key"
}

Example

curl https://api.feeds.onhelix.ai/writers \
-H "Authorization: Bearer YOUR_API_KEY"

Get Writer

Retrieve a specific writer by ID.

GET /writers/:writerId

Request

Headers:

Authorization: Bearer YOUR_API_KEY

Path Parameters:

ParameterTypeRequiredDescription
writerIdstringYesWriter identifier

Response

Status: 200 OK

{
"success": true,
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"organizationId": "org-uuid-here",
"name": "Tech Blog Writer",
"description": "Writes technical blog posts for developers",
"styleGuide": "Use clear, direct language. Avoid jargon unless necessary.",
"toneMatrix": { "formality": "casual", "enthusiasm": "high" },
"exampleBank": [],
"bannedLanguage": [],
"constitution": [],
"audienceProfile": "Software engineers with 2-10 years of experience",
"maxLength": 2000,
"minLength": 500,
"formattingRules": null,
"maxEditPasses": 3,
"qualityThreshold": 0.7,
"evaluationDimensions": [
"clarity",
"completeness",
"tone",
"coherence",
"accuracy"
],
"structuredOutputSchema": null,
"humanize": true,
"otherInstructions": null,
"contentBriefTemplate": null,
"createdAt": "2026-01-15T10:00:00.000Z",
"updatedAt": "2026-01-15T10:00:00.000Z",
"deletedAt": null
}
}

Errors

401 Unauthorized:

{
"success": false,
"error": "Invalid or missing API key"
}

404 Not Found:

{
"success": false,
"error": "Writer not found: a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

Example

curl https://api.feeds.onhelix.ai/writers/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer YOUR_API_KEY"

Update Writer

Update an existing writer's configuration. Only fields included in the request body are updated.

PATCH /writers/:writerId

Request

Headers:

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Path Parameters:

ParameterTypeRequiredDescription
writerIdstringYesWriter identifier

Body:

{
"styleGuide": "Use a more formal tone. Avoid contractions.",
"maxLength": 3000
}

Parameters:

Accepts all fields from Create Writer. All fields are optional; only fields present in the request body are modified.

Sending an empty body {} is a valid request -- it updates only the updatedAt timestamp.

Response

Status: 200 OK

{
"success": true,
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"organizationId": "org-uuid-here",
"name": "Tech Blog Writer",
"description": "Writes technical blog posts for developers",
"styleGuide": "Use a more formal tone. Avoid contractions.",
"toneMatrix": { "formality": "casual", "enthusiasm": "high" },
"exampleBank": [],
"bannedLanguage": [],
"constitution": [],
"audienceProfile": "Software engineers with 2-10 years of experience",
"maxLength": 3000,
"minLength": 500,
"formattingRules": null,
"maxEditPasses": 3,
"qualityThreshold": 0.7,
"evaluationDimensions": [
"clarity",
"completeness",
"tone",
"coherence",
"accuracy"
],
"structuredOutputSchema": null,
"humanize": true,
"otherInstructions": null,
"contentBriefTemplate": null,
"createdAt": "2026-01-15T10:00:00.000Z",
"updatedAt": "2026-01-15T11:30:00.000Z",
"deletedAt": null
}
}

Errors

400 Bad Request:

{
"success": false,
"error": "Validation error: maxLength must be at least 1"
}
{
"success": false,
"error": "A writer with this name already exists in your organization"
}

401 Unauthorized:

{
"success": false,
"error": "Invalid or missing API key"
}

404 Not Found:

{
"success": false,
"error": "Writer not found: a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

Example

curl -X PATCH https://api.feeds.onhelix.ai/writers/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"styleGuide": "Use a more formal tone. Avoid contractions.",
"maxLength": 3000
}'

Delete Writer

Delete a writer. The writer is soft-deleted and will no longer appear in list results or accept new jobs. Existing in-progress jobs are not affected, and completed job results remain retrievable using the original writerId.

DELETE /writers/:writerId

Request

Headers:

Authorization: Bearer YOUR_API_KEY

Path Parameters:

ParameterTypeRequiredDescription
writerIdstringYesWriter identifier

Response

Status: 204 No Content

No response body is returned.

Errors

401 Unauthorized:

{
"success": false,
"error": "Invalid or missing API key"
}

404 Not Found:

{
"success": false,
"error": "Writer not found: a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

Example

curl -X DELETE https://api.feeds.onhelix.ai/writers/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer YOUR_API_KEY"

Start Writing Job

Submit a writing request to a writer. Returns immediately with a job ID. The writing job runs asynchronously -- poll the status endpoint or retrieve results when ready.

POST /writers/:writerId/jobs

Request

Headers:

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Path Parameters:

ParameterTypeRequiredDescription
writerIdstringYesWriter identifier

Body:

{
"prompt": "Write a blog post about the benefits of TypeScript for large codebases.",
"jobId": "my-blog-post-job-001",
"research": "TypeScript adoption has grown 50% year-over-year according to the Stack Overflow survey...",
"toneContext": "The audience just attended a conference on developer productivity"
}

Parameters:

ParameterTypeRequiredDescription
promptstringYesWriting instruction (1--100,000 chars)
jobIdstringNoIdempotency key (1--256 chars, alphanumeric, hyphens, underscores)
researchstringNoResearch context to inform the writing (1--100,000 chars)
toneContextstringNoPer-job tone guidance (1--10,000 chars)
overridesobjectNoOverride writer profile fields for this job only. Only fields valid on a writer profile are accepted.

Response

Status: 202 Accepted

{
"success": true,
"data": {
"jobId": "my-blog-post-job-001"
}
}

Response Fields:

FieldTypeDescription
jobIdstringJob identifier. Use this to check status and retrieve results

Idempotency

Submitting a request with an existing jobId reconnects to the running, pending, or completed job instead of starting a new one. If the previous job with that jobId failed, the API returns a 400 error -- use a new jobId to retry.

Errors

400 Bad Request:

{
"success": false,
"error": "Validation error: prompt must be at least 1 character"
}
{
"success": false,
"error": "Previous writer job failed. Please retry with a new jobId."
}

401 Unauthorized:

{
"success": false,
"error": "Invalid or missing API key"
}

404 Not Found:

{
"success": false,
"error": "Writer not found: a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

500 Internal Server Error:

{
"success": false,
"error": "Failed to start writer job."
}

Example

curl -X POST https://api.feeds.onhelix.ai/writers/a1b2c3d4-e5f6-7890-abcd-ef1234567890/jobs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Write a blog post about the benefits of TypeScript for large codebases.",
"jobId": "my-blog-post-job-001"
}'

Check Job Status

Check the current status of a writing job.

GET /writers/:writerId/jobs/:jobId/status

Request

Headers:

Authorization: Bearer YOUR_API_KEY

Path Parameters:

ParameterTypeRequiredDescription
writerIdstringYesWriter identifier
jobIdstringYesJob identifier ([a-zA-Z0-9_-]+)

Response

Status: 200 OK

{
"success": true,
"data": {
"jobId": "my-blog-post-job-001",
"status": "running"
}
}

Response Fields:

FieldTypeDescription
jobIdstringJob identifier
statusstringCurrent job status

Status Values:

StatusDescription
pendingJob created, workflow starting
runningJob actively processing
completedJob finished, results available
failedJob failed

Errors

401 Unauthorized:

{
"success": false,
"error": "Invalid or missing API key"
}

404 Not Found:

{
"success": false,
"error": "Job not found: my-blog-post-job-001"
}

Example

curl "https://api.feeds.onhelix.ai/writers/a1b2c3d4-e5f6-7890-abcd-ef1234567890/jobs/my-blog-post-job-001/status" \
-H "Authorization: Bearer YOUR_API_KEY"

Get Job Result

Retrieve the result of a completed writing job.

GET /writers/:writerId/jobs/:jobId

Request

Headers:

Authorization: Bearer YOUR_API_KEY

Path Parameters:

ParameterTypeRequiredDescription
writerIdstringYesWriter identifier
jobIdstringYesJob identifier ([a-zA-Z0-9_-]+)

Important: Always check the job status endpoint first. Calling this endpoint on a pending or running job returns a 500 error, not a partial result.

Response

Status: 200 OK

The response shape depends on whether the writer was configured with a structuredOutputSchema.

Plain text result (no structuredOutputSchema):

{
"success": true,
"data": {
"status": "completed",
"content": "TypeScript has transformed how teams build large-scale applications...",
"outline": {
"sections": [
{
"title": "Introduction",
"summary": "Overview of TypeScript adoption"
},
{ "title": "Type Safety at Scale", "summary": "How types prevent bugs" }
]
},
"metadata": {
"wordCount": 1243,
"editPasses": 2,
"qualityScore": 0.89
}
}
}

Structured result (with structuredOutputSchema):

{
"success": true,
"data": {
"status": "completed",
"structuredContent": {
"title": "Why TypeScript Is Essential for Large Codebases",
"sections": [
{
"heading": "Introduction",
"body": "TypeScript has transformed how teams build large-scale applications..."
}
],
"summary": "A comprehensive look at TypeScript's benefits for enterprise teams."
},
"outline": {
"sections": [
{
"title": "Introduction",
"summary": "Overview of TypeScript adoption"
},
{ "title": "Type Safety at Scale", "summary": "How types prevent bugs" }
]
},
"metadata": {
"wordCount": 1243,
"editPasses": 2,
"qualityScore": 0.89
}
}
}

Response Fields:

FieldTypeDescription
statusstringJob status (completed). For failed jobs, this endpoint returns a 500 error -- check the status endpoint first.
contentstringWritten content as plain text (present when no structuredOutputSchema)
structuredContentobjectWritten content conforming to the writer's structuredOutputSchema (present when schema is configured)
outlineobjectThe structural outline generated before writing
metadataobjectJob metadata including word count, edit passes, and quality score

Errors

401 Unauthorized:

{
"success": false,
"error": "Invalid or missing API key"
}

404 Not Found:

{
"success": false,
"error": "Job not found: my-blog-post-job-001"
}

500 Internal Server Error:

{
"success": false,
"error": "Writer job failed. Please retry with a new jobId."
}
{
"success": false,
"error": "Writer job is still processing. Poll GET /writers/:writerId/jobs/:jobId/status and retry when completed."
}

Handling Failed Jobs

If a job fails:

  1. The status endpoint reports failed
  2. The result endpoint returns a 500 error -- failure details are not currently exposed in the API response
  3. Retry by submitting a new job with a different jobId

Common causes of job failure include workflow timeouts (jobs exceeding 60 minutes) and transient infrastructure errors.

Example

curl "https://api.feeds.onhelix.ai/writers/a1b2c3d4-e5f6-7890-abcd-ef1234567890/jobs/my-blog-post-job-001" \
-H "Authorization: Bearer YOUR_API_KEY"

Error Responses

All endpoints may return these standard errors:

400 Bad Request

Invalid request parameters or body:

{
"success": false,
"error": "Validation error: name must be at least 1 character"
}

401 Unauthorized

Missing or invalid API key:

{
"success": false,
"error": "Invalid or missing API key"
}

404 Not Found

Resource not found:

{
"success": false,
"error": "Writer not found: a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

500 Internal Server Error

Server error:

{
"success": false,
"error": "An internal error occurred. Please try again later."
}

Next Steps