Heyzeva/API Documentation

API Documentation

Generate GEO-optimized blog posts programmatically. Use the MCP server with Claude Code or any MCP client, or call the REST API directly.

Base URL
https://heyzeva.com/api/v1

Authentication

All requests require a Bearer token. Generate an API key from your dashboard.

Header
Authorization: Bearer hz_live_your_key_here

API access requires a paid plan (Starter, Pro, or Scale).

Errors

All errors return a consistent JSON shape:

{
  "type": "error",
  "code": "ERROR_CODE",
  "message": "Human-readable description"
}

Common error codes

401UNAUTHORIZED — Missing or invalid API key
403NO_SUBSCRIPTION — No active paid plan
429QUOTA_EXCEEDED — Monthly post limit reached
429DAILY_OUTLINE_LIMIT — Max 50 outlines per day

MCP Server

Connect from Claude Code or any MCP client using JSON-RPC 2.0 over HTTP.

Option 1: Terminal (recommended)
claude mcp add heyzeva \
  --transport http \
  --url "https://heyzeva.com/api/mcp" \
  --header "Authorization: Bearer hz_live_your_key_here"
Option 2: Save as .mcp.json in your project root
{
  "mcpServers": {
    "heyzeva": {
      "type": "http",
      "url": "https://heyzeva.com/api/mcp",
      "headers": {
        "Authorization": "Bearer hz_live_your_key_here"
      }
    }
  }
}

Available Tools

create_outline(prompt*, content_type?, force?)

Generate a blog post outline from a topic prompt. Returns title, sections, FAQ, and an outline_id to use with publish_post.

publish_post(outline_id*)

Confirm an outline and start the generation pipeline. Posts take ~5 minutes.

check_status(topic_id*)

Track generation progress. Returns phase (research → enrichment → post) and estimated time.

get_post(post_id*)

Retrieve full post content: markdown, sanitized HTML, citations, FAQ, JSON-LD, hero image, internal links.

list_posts(status?, limit?, search?)

List posts with filtering and pagination. Returns URLs, GEO scores, and edit counts.

edit_post(post_id*, instruction*, section?)

Edit a published post with natural language instructions. Max 2 edits per post.

retry_post(topic_id*)

Retry a failed post generation from the beginning.

get_quota((none))

Check your plan, usage, and remaining post quota.

Typical workflow

1. create_outline → review the outline

2. publish_post → start generation

3. check_status → poll until completed (~5 min)

4. get_post → retrieve the full post

5. edit_post → refine if needed (max 2 edits)

POST/api/v1/outline

Generate a blog post outline from a topic prompt.

Request body

prompt*
string
Topic or title for the blog post.
content_type
string
One of: standard, how-to, listicle, comparison, guide. Defaults to AI selection.
force
boolean
Skip duplicate check. Use when warned about existing similar posts.
Response — outline
{
  "type": "outline",
  "outline_id": "job-abc123",
  "title": "10 Ways Construction PMs Save Time",
  "meta_description": "Discover proven strategies...",
  "sections": [
    { "h2": "Section Title", "key_points": ["point 1", "point 2"] }
  ],
  "faq_questions": ["What is...?", "How does...?"],
  "topic_metadata": {
    "title": "...", "slug": "...", "keyword": "...",
    "buyer_stage": "awareness", "pillar": "Efficiency",
    "content_type": "listicle"
  },
  "quota": { "used": 3, "limit": 8, "remaining": 5 }
}
Response — clarification needed
{
  "type": "clarification_needed",
  "message": "Your prompt is too vague...",
  "questions": ["What aspect of construction?"],
  "suggestions": ["10 PM tools for residential builders"]
}

Status codes

200Outline generated or clarification needed
403NO_SUBSCRIPTION
429QUOTA_EXCEEDED or DAILY_OUTLINE_LIMIT
POST/api/v1/posts

Confirm an outline and start the full post generation pipeline (~5 min).

Request body

outline_id*
string
The outline_id from a create_outline response.
Response
{
  "type": "accepted",
  "topic_id": "topic-abc123",
  "message": "Post generation started. Use check_status to track progress."
}

Status codes

200Generation started
404OUTLINE_NOT_FOUND
410OUTLINE_EXPIRED — outlines expire after 4 hours
429QUOTA_EXCEEDED
GET/api/v1/posts

List posts with filtering, search, and pagination.

Query parameters

status
string
Filter: published (default), draft, or all.
limit
number
Results per page (1-50, default 10).
offset
number
Skip N results for pagination.
since
string
ISO date — only posts published after this date.
search
string
Filter posts by title substring.
Response
{
  "posts": [
    {
      "id": "post-abc123",
      "title": "10 Ways Construction PMs Save Time",
      "url": "https://buildtrack.heyzeva.com/10-ways-pms-save-time",
      "status": "published",
      "content_type": "listicle",
      "geo_score": 91,
      "published_at": "2026-03-20T10:00:00Z",
      "edits_remaining": 2
    }
  ],
  "total": 24,
  "has_more": true,
  "quota": { "used": 3, "limit": 8, "remaining": 5 }
}
GET/api/v1/posts/:id

Retrieve full post content including markdown, HTML, citations, FAQ, and SEO data.

Response
{
  "id": "post-abc123",
  "title": "10 Ways Construction PMs Save Time",
  "slug": "10-ways-pms-save-time",
  "url": "https://buildtrack.heyzeva.com/10-ways-pms-save-time",
  "status": "published",
  "content_type": "listicle",
  "content": "# 10 Ways Construction PMs Save Time\n\n...",
  "content_html": "<h1>10 Ways Construction PMs Save Time</h1>...",
  "excerpt": "Discover proven strategies...",
  "meta_title": "10 Ways Construction PMs Save Time | BuildTrack",
  "meta_description": "Discover proven strategies...",
  "hero_image": {
    "url": "https://images.unsplash.com/...",
    "alt": "Construction project manager reviewing plans",
    "photographer": "John Doe",
    "photographer_url": "https://unsplash.com/@johndoe"
  },
  "geo_score": 91,
  "faq": [
    { "question": "What is a construction PM?", "answer": "..." }
  ],
  "citations": [
    { "url": "https://example.com/source", "title": "Source Title" }
  ],
  "internal_links": [
    {
      "slug": "construction-pm-tools",
      "title": "Best Construction PM Tools",
      "anchor_text": "PM tools guide",
      "heyzeva_url": "https://buildtrack.heyzeva.com/construction-pm-tools"
    }
  ],
  "json_ld": { "@type": "Article", ... },
  "topic": {
    "keyword": "construction PM",
    "pillar": "Efficiency",
    "buyer_stage": "awareness"
  },
  "word_count": 2450,
  "reading_time": "13 min read",
  "edits_remaining": 2,
  "published_at": "2026-03-20T10:00:00Z",
  "created_at": "2026-03-20T09:45:00Z",
  "updated_at": "2026-03-20T10:00:00Z"
}

Status codes

200Post returned (cached: 60s, stale-while-revalidate: 300s)
404POST_NOT_FOUND
GET/api/v1/posts/:id/status

Check post generation progress. The :id is the topic_id returned by publish.

Response — processing
{
  "status": "processing",
  "phase": "enrichment",
  "phase_label": "Enriching content with GEO signals",
  "phases_completed": ["research"],
  "estimated_remaining_seconds": 180
}
Response — completed
{
  "status": "completed",
  "post": {
    "id": "post-abc123",
    "title": "10 Ways Construction PMs Save Time",
    "url": "https://buildtrack.heyzeva.com/10-ways-pms-save-time",
    "geo_score": 91,
    "published_at": "2026-03-20T10:00:00Z",
    "edits_remaining": 2
  }
}
Response — failed
{
  "status": "failed",
  "error": "AI timeout during enrichment",
  "can_retry": true,
  "topic_id": "topic-abc123",
  "instruction": "Use retry_post with this topic_id"
}
POST/api/v1/posts/:id/edit

Edit a published post with natural language instructions. Max 2 edits per post.

Request body

instruction*
string
Natural language edit instruction (e.g., "Make the intro more engaging").
section
string
Target a specific H2 section by title.
Response
{
  "type": "edited",
  "geo_score": 89,
  "edits_remaining": 1
}

Status codes

200Edit applied
400Missing instruction
422EDIT_FAILED — edit limit reached or internal error
POST/api/v1/posts/:id/retry

Retry a failed post generation. The :id is the topic_id.

No request body required.

Response
{
  "type": "accepted",
  "topic_id": "topic-abc123",
  "message": "Retry generation started. Use check_status to track progress."
}

Status codes

200Retry started
404Topic not found
409TOPIC_NOT_FAILED — topic is not in failed state
GET/api/v1/quota

Check your plan, usage, and remaining post quota for the current billing period.

Response
{
  "plan": "pro",
  "used": 3,
  "limit": 8,
  "remaining": 5,
  "resets_at": "2026-04-01T00:00:00Z",
  "site": {
    "name": "BuildTrack",
    "slug": "buildtrack"
  }
}

Status codes

200Quota info returned
403NO_SUBSCRIPTION

Need help? Contact us at support@heyzeva.com