---
name: talkgenai
description: Write a researched, SEO-structured article and publish it to a WordPress site (Webflow, Shopify and Wix on request), and find Reddit posts where people ask for what the user sells and draft replies they post themselves. Use when the user wants a blog post written or published to their own site, or wants Reddit leads and reply drafts.
homepage: https://app.talkgen.ai
---

# TalkGenAI

Generate a full SEO article and put it on the user's site.

Agents can already write. What they usually cannot do is get the result onto someone's
WordPress with a hero image, FAQ schema, internal links and a meta description in place.
That is what this API is for.

**Base URL:** `https://app.talkgen.ai`
**Docs:** <https://docs.talkgen.ai> (setup per client, every tool, every error code)
**Auth:** `Authorization: Bearer tgai_...` on every request.

**Where the key is:** look for `TALKGENAI_API_KEY` in the environment or in a local `.env`
file. If it is not there, stop and ask the user for it rather than guessing. They create one
at <https://app.talkgen.ai/connect-agent> (free account, no card, about 3 articles of
starting credit). Treat it like a password: it can publish to the user's live site. Never
print it, log it, or write it into a file you commit.

**Cost:** 5 credits per article, 8 with an image. Reading and publishing are free.

---

## If your client speaks MCP, use that instead

There is a Model Context Protocol server at `https://app.talkgen.ai/mcp`. It exposes the same
commands as native tools, so the client discovers them itself and you can ignore the rest of
this file.

```bash
# Claude Code
claude mcp add --transport http talkgenai https://app.talkgen.ai/mcp \
  --header "Authorization: Bearer $TALKGENAI_API_KEY"
```

```jsonc
// Cursor (.cursor/mcp.json) or VS Code (.vscode/mcp.json)
{
  "mcpServers": {
    "talkgenai": {
      "type": "http",
      "url": "https://app.talkgen.ai/mcp",
      "headers": { "Authorization": "Bearer tgai_your_key_here" }
    }
  }
}
```

Claude Desktop reaches remote servers through `mcp-remote`:

```jsonc
{
  "mcpServers": {
    "talkgenai": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://app.talkgen.ai/mcp",
               "--header", "Authorization: Bearer tgai_your_key_here"]
    }
  }
}
```

Tools: `list_sites` · `get_content_plan` · `generate_article` · `get_article` ·
`publish_article` · `check_credits` · `get_rankings`. Same key, same credits, same
draft-by-default rule.

Reddit agent tools (accounts with the Reddit agent): `reddit_get_settings` ·
`reddit_list_leads` · `reddit_draft_reply` · `reddit_mark_lead` · `reddit_run_scan`.
See [Reddit agent](#reddit-agent).

The rest of this file is the plain HTTP version, for agents without an MCP client.

---

## The whole loop

Write an article and leave it as a draft on the user's site:

```bash
# The key lives here. Set it once per shell.
export TALKGENAI_API_KEY=tgai_your_key_here
AUTH="Authorization: Bearer $TALKGENAI_API_KEY"

# 1. Which sites can I publish to?  (copy connection_id from the response)
curl -s -H "$AUTH" https://app.talkgen.ai/api/v1/sites

# 2. Start the article (costs 5 credits, returns immediately)
JOB=$(curl -s -X POST https://app.talkgen.ai/api/v1/articles \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"title":"How to choose a CRM for a 5-person agency","length":"medium"}' \
  | jq -r .job_id)

# 3. Poll every 10s until status is "completed" (45-360s depending on length)
curl -s -H "$AUTH" https://app.talkgen.ai/api/v1/articles/$JOB

# 4. Publish it as a DRAFT to the site from step 1
curl -s -X POST https://app.talkgen.ai/api/v1/articles/$JOB/publish \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"connection_id":"wpc_abc123"}'
```

Every example below assumes `$AUTH` is set as above.

Step 4 creates a **draft**, not a live post. To publish live, pass
`{"connection_id":"wpc_abc123","status":"publish"}` — see [Publishing safely](#publishing-safely).

---

## Working the content plan (the better loop)

If the user has a content plan, work from it instead of inventing titles. The plan already
holds the target keyword, the H2 outline, the word count and the strategic reason, and the
card is marked off automatically when you write it.

```bash
# 1. What is still open?
curl -s -H "$AUTH" https://app.talkgen.ai/api/v1/content-plan
```

```json
{
  "has_plan": true,
  "plan_id": "plan_7f3a2b",
  "domain": "example.com",
  "totals": { "planned": 21, "manually_written": 2, "published": 9 },
  "matching": 21,
  "cards": [
    {
      "card_index": 4,
      "title": "How to choose a CRM for a 5-person agency",
      "keyword": "crm for small agency",
      "month": 3,
      "status": "planned",
      "search_intent": "Commercial",
      "content_type": "Comparison",
      "suggested_length": "long",
      "h2_outline": ["Start with cost per seat", "Onboarding time", "Verdict"],
      "strategic_reason": "Buyers compare tools here before choosing.",
      "search_volume": 450,
      "keyword_difficulty": 12
    }
  ]
}
```

```bash
# 2. Write that card. No title needed - the brief comes from the plan.
curl -s -X POST https://app.talkgen.ai/api/v1/articles \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"plan_id":"plan_7f3a2b","card_index":4}'
```

The card is marked `manually_written` when generation finishes and `published` when you
publish it. You do not have to report anything back.

Filters: `?status=planned` · `?month=3` · `?limit=20` · `?include_done=true` ·
`?domain=example.com`. By default only OPEN cards are returned, so you will not repeat work.

⚠️ Agents cannot create a plan or change its schedule. A plan costs 20 credits and some
tiers get only one, so that stays a human decision.

---

## Commands

### List sites

```bash
curl -s -H "$AUTH" https://app.talkgen.ai/api/v1/sites
```

```json
{
  "sites": [
    {
      "connection_id": "wpc_9f2c41d7a8b3e05c6d1f2a4b",
      "site_url": "https://example.com",
      "site_name": "Example Blog",
      "platform": "wordpress",
      "auth_method": "plugin_token"
    }
  ],
  "count": 1
}
```

If `count` is 0, the user has not connected a site yet. Send them to
<https://app.talkgen.ai/dashboard> to connect one. You can still generate articles without
a site and hand back the HTML.

### Generate an article

```bash
curl -s -X POST https://app.talkgen.ai/api/v1/articles \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{
    "title": "How to choose a CRM for a 5-person agency",
    "topic": "Practical buying guide for small agencies, focused on cost per seat and onboarding time",
    "length": "medium",
    "image": true,
    "focus_keyword": "crm for small agency"
  }'
```

| Field | Default | Notes |
|---|---|---|
| `title` | required | The article's headline. |
| `topic` | falls back to `title` | The angle or brief. Worth writing: it drives the whole piece. |
| `length` | `medium` | `short` (~500w) · `medium` (~900w) · `long` (~1400w) · `very_large` · `pillar` |
| `image` | `false` | Generates a hero image. Costs 3 extra credits. |
| `focus_keyword` | none | Target keyword for on-page SEO. |
| `instructions` | none | Free text: tone, audience, things to avoid. |
| `include_faq` | `true` | Appends an FAQ block with FAQ schema. |
| `include_external_link` | `true` | Cites outbound sources. |
| `brand_voice_id` | none | Use a brand voice the user trained in the dashboard. |
| `plan_id` + `card_index` | none | Write a content-plan card. Fills in title, keyword, length, outline and angle, and marks the card off. |

```json
{
  "success": true,
  "job_id": "job_1a2b3c4d5e6f",
  "status": "pending",
  "estimated_time": 90,
  "credits_remaining": 26,
  "poll_url": "https://app.talkgen.ai/api/v1/articles/job_1a2b3c4d5e6f"
}
```

### Poll for the result

```bash
curl -s -H "$AUTH" https://app.talkgen.ai/api/v1/articles/job_1a2b3c4d5e6f
```

While it runs:

```json
{ "job_id": "job_1a2b3c4d5e6f", "status": "processing", "progress": 30 }
```

When it finishes:

```json
{
  "job_id": "job_1a2b3c4d5e6f",
  "status": "completed",
  "progress": 100,
  "title": "How to Choose a CRM for a 5-Person Agency",
  "html": "<h2>Start with cost per seat</h2><p>...",
  "seo_title": "How to Choose a CRM for a Small Agency (2026 Guide)",
  "meta_description": "A practical buying guide for agencies under 10 people...",
  "focus_keyword": "crm for small agency",
  "word_count": 912,
  "has_image": true
}
```

`status` is one of `pending`, `processing`, `completed`, `failed`. On `failed` there is an
`error` field. **Poll every 5 to 10 seconds, not continuously** — free endpoints are limited
to roughly 60 requests a minute per key.

### Publish

```bash
curl -s -X POST https://app.talkgen.ai/api/v1/articles/job_1a2b3c4d5e6f/publish \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"connection_id":"wpc_9f2c41d7a8b3e05c6d1f2a4b"}'
```

```json
{
  "success": true,
  "post_id": 4471,
  "post_url": "https://example.com/?p=4471",
  "edit_url": "https://example.com/wp-admin/post.php?post=4471&action=edit",
  "status": "draft",
  "note": "Saved as a draft. It is not public yet. Open edit_url to review, or publish with {\"status\": \"publish\"}."
}
```

The hero image is uploaded and set as the featured image automatically. Publishing the same
article to the same site twice updates the existing post instead of creating a duplicate, so
a retry after a timeout is safe.

### Check credits

```bash
curl -s -H "$AUTH" https://app.talkgen.ai/api/v1/credits
```

```json
{
  "plan": "free",
  "credits_remaining": 24,
  "bonus_credits": 11,
  "total_available": 35,
  "costs": { "article": 5, "article_with_image": 8, "publish": 0, "read": 0 }
}
```

### Rankings (Growth plan and above)

```bash
curl -s -H "$AUTH" "https://app.talkgen.ai/api/v1/rankings?site=https://example.com"
```

Returns Google Search Console positions, clicks and impressions for the connected site.
Useful for deciding what to write next rather than guessing. Returns `403
plan_upgrade_required` on Free and Starter.

---

## Reddit agent

If the account has the Reddit agent (free first scan, then $49/month, included in Pro and
Scale), you can work its leads: Reddit posts where people ask for what the user sells, found
by a daily scan and checked by AI against the user's business description.

**It never posts.** You find leads and draft replies. The user reads the draft, edits it and
posts it from their own Reddit account. Never claim a reply was posted, and never try to post
it through any other tool or account.

```bash
# 1. Is it set up, and what does it watch?
curl -s -H "$AUTH" https://app.talkgen.ai/api/v1/reddit/settings

# 2. Today's open leads, best first
curl -s -H "$AUTH" "https://app.talkgen.ai/api/v1/reddit/leads?min_score=50&limit=5"

# 3. Draft a reply for one (free, up to 10 a day, ~10 seconds)
curl -s -X POST -H "$AUTH" https://app.talkgen.ai/api/v1/reddit/leads/LEAD_ID/draft

# 4. After the USER has posted it
curl -s -X POST -H "$AUTH" -H "Content-Type: application/json" \
  https://app.talkgen.ai/api/v1/reddit/leads/LEAD_ID/status -d '{"status":"replied"}'
```

A lead looks like:

```json
{
  "lead_id": "66f1c0...",
  "title": "What do you use to track customer feedback from support tickets?",
  "url": "https://www.reddit.com/r/SaaS/comments/...",
  "subreddit": "SaaS",
  "comments": 1,
  "score": 78,
  "intent": "recommendation",
  "why_it_matched": "asks for a tool in your category",
  "draft_reply": null,
  "status": "new"
}
```

Lead statuses: `new` · `saved` · `replied` · `ignored`. `POST /api/v1/reddit/scan` queues a
fresh scan (3 a day; it starts within about 5 minutes). On a free trial only the top 3 leads
are readable and the rest come back `"locked": true`; drafting a locked lead returns `402`.
Without the Reddit agent every call returns `403 reddit_agent_not_enabled`.

---

## Publishing safely

**`status` defaults to `draft`.** You have to ask for a live post:

```json
{ "connection_id": "wpc_...", "status": "publish" }
```

This is deliberate, and it overrides whatever default the user set in their dashboard.
Publishing to someone's real website is not reversible in the way a draft is — the post can
be indexed, shared or seen before anyone notices a mistake.

**If you are an agent running without a human watching each step, publish drafts.** Give the
user the `edit_url` and let them press the button. Only pass `status: "publish"` when the
user has actually asked for the post to go live.

A workspace can also switch live publishing off for agents entirely. If it has,
`status: "publish"` returns `403 live_publish_disabled` and there is no way around it. Save
a draft and tell the user.

---

## Errors

Every error is JSON with a `code` and a `message` you can show the user.

| Status | `code` | What to do |
|---|---|---|
| 401 | `unauthorized` | Key is missing, malformed or revoked. Get a new one at `/connect-agent`. |
| 403 | `insufficient_credits` | Out of credits. The response has `credit_cost` and `upgrade_url`. |
| 403 | `domain_mismatch` | You are using a WordPress *plugin* key, which is locked to one site. Create an **agent key** at `/connect-agent` instead. |
| 403 | `plan_upgrade_required` | Feature is on a higher plan. `upgrade_url` is in the response. |
| 400 | `not_ready` | The article has not finished generating. Keep polling. |
| 404 | `site_not_found` | Bad `connection_id`. Re-read `GET /api/v1/sites`. |
| 404 | `plan_not_found` / `card_not_found` | Re-read `GET /api/v1/content-plan`. |
| 409 | `card_already_published` | That card is done. Pick another. |
| 403 | `live_publish_disabled` | This workspace forbids agents publishing live. Save a draft instead. |
| 403 | `scope_missing` | This key was created without that permission (articles, publish or reddit). Tell the user; they can create a key with it in the dashboard. |
| 403 | `agent_key_not_allowed_here` | Agent keys only work on `/api/v1/*` and `/mcp`. |
| 403 | `reddit_agent_not_enabled` | The account has no Reddit agent. It starts free at `/reddit-agent`. |
| 429 | `rate_limited` | Slow the polling down. Retry after 60s. |

A free account cannot spend its monthly credits on images: image generation has to be
covered by bonus credits. If `image: true` returns `insufficient_credits` on a free plan
while `total_available` looks sufficient, generate without the image, or upgrade.

---

## Notes

- Generation is asynchronous. There is no synchronous "give me the article now" call, and a
  `long` or `pillar` article genuinely takes several minutes.
- The article HTML is returned to you as well as published, so you can post it somewhere
  else, save it to a file, or show it to the user before publishing.
- WordPress works for every account. Webflow, Shopify and Wix are turned on per account (email support@talkgen.ai); once enabled they use the same `connection_id`. `GET /api/v1/sites` lists only the sites the account has connected.
- Read endpoints are free but limited to about 60 requests per minute per key. That limit is
  best effort, not a hard guarantee.
