Docs
Pricing Log in
Documentation

AI Generation

Generate a poll or quiz draft from an article. Generation runs async — a job is queued, and the resulting draft is reviewed, edited, and published separately. See Drafts.

Send an article (by URL or raw text) and get back a draft, not a live poll/quiz — nothing is published until you (or auto_publish) say so. See Drafts for reviewing, editing, and publishing the result.

Every question is grounded in the article's own text — the model is instructed never to invent facts, and self-reports is_grounded per question and an overall confidence. A draft with an ungrounded question, or whose confidence falls below your account's minimum, is flagged: it still appears for review, but can never auto-publish. By default, submitting an article that's substantially about a tragedy, an active election, or a health crisis skips generation entirely and the job comes back flagged with no draft at all — pass check_sensitive_topics: false to turn this screening off.

Plan limits

Each plan includes a monthly allowance of AI generations, shared across every site on the account (see your plan's details). A repeat save of the same article (same text, type, and question_count) always reuses the first run's draft and never counts against this allowance. Once it's used up, POST /generate returns 429 Too Many Requests until the monthly reset.

Trait-mapping suggestions and auto_publish require the Pro plan or above. On Free or Starter, a draft is generated normally but with no suggested trait mappings, and auto_publish is silently ignored (the draft is always created for review) — both are called out in the job's notices, alongside an upgrade_url.

MethodEndpointAuthDescription
POST/generateAPI keyQueue a poll/quiz generation job
GET/generate/{job}API keyCheck a generation job's status
POST /generate API key

Queue a generation job

FieldTypeRules
article_urlstringRequired unless article_text is given (exactly one of the two) — the page is fetched and its readable text extracted server-side.
article_textstringRequired unless article_url is given — skip the fetch and hand over the article's text directly.
typestringRequired, one of poll, quiz. (Not survey — a poll is a single question; a true multi-step survey isn't generated by this endpoint.)
question_countintegerRequired, 1 up to your account's configured maximum. A poll is always exactly 1 question.
tonestringOptional — a short style hint passed to the model, e.g. "playful" or "serious".
auto_publishbooleanOptional, defaults to false. Ignored (never publishes) if the resulting draft is flagged, regardless of this value.
check_sensitive_topicsbooleanOptional, defaults to true. Set to false to skip the sensitive-topic screening entirely — the job is never flagged for subject matter (an ungrounded question or low confidence can still flag it).
webhook_urlstringOptional — POSTed once the job finishes (completed, failed, or flagged), unsigned. See the payload shape below.
site_idintegerOptional, same rules as Poll's site_id.
REQUEST
curl -X POST https://qnaapi.com/api/v1/generate \
  -H "X-API-Key: qna_..." \
  -H "Content-Type: application/json" \
  -d '{
    "article_url": "https://example.com/news/playoff-recap",
    "type": "quiz",
    "question_count": 5,
    "auto_publish": false
  }'
202 ACCEPTED
{
  "data": {
    "job_id": 42,
    "status": "pending",
    "type": "quiz",
    "draft_id": null,
    "error_message": null,
    "flagged_reason": null,
    "model": null,
    "prompt_version": null,
    "input_tokens": null,
    "output_tokens": null,
    "latency_ms": null,
    "notices": [],
    "upgrade_url": null,
    "started_at": null,
    "completed_at": null,
    "created_at": "2026-10-02T00:00:00.000000Z"
  }
}
Submitting the same article's text twice (same type and question_count) reuses the first run's draft and skips generation entirely — no credit is used on a repeat save of the same post.

Once your monthly AI generation credits are used up:

429 TOO MANY REQUESTS
{
  "message": "You've used all 25 AI generation credits for this plan this month.",
  "error": "generation_credits_exhausted",
  "credits_reset_at": "2026-11-01T00:00:00+00:00",
  "upgrade_url": "https://qnaapi.com/checkout/pro"
}

On Free or Starter, requesting auto_publish or receiving trait suggestions that your plan doesn't support shows up in the created job instead of an error:

202 ACCEPTED (Free/Starter, auto_publish requested)
{
  "data": {
    "job_id": 43,
    "status": "pending",
    "notices": [
      "auto_publish requires the Pro plan or above — this draft was generated for review only.",
      "Trait mapping suggestions require the Pro plan or above — this draft has no suggested trait mappings."
    ],
    "upgrade_url": "https://qnaapi.com/checkout/pro"
  }
}

If webhook_url is given, this JSON body is POSTed to it once the job reaches a final status:

WEBHOOK PAYLOAD
{
  "job_id": 42,
  "status": "completed",
  "draft_id": 7,
  "error": null,
  "flagged_reason": null
}
GET /generate/{job} API key

Check a generation job

REQUEST
curl -H "X-API-Key: qna_..." https://qnaapi.com/api/v1/generate/42
StatusMeaning
pendingQueued, not yet started
processingFetching the article and/or generating
completedA draft was created — see draft_id
flaggedSkipped generation — the article matched a sensitive-topic rule. No draft was created; see flagged_reason.
failedCouldn't fetch the article, or generation failed twice in a row — see error_message.
credits_exhaustedRare — credits ran out between the initial request and the job actually running. No draft was created; see upgrade_url.

A completed job's draft may itself be flagged for low confidence or an ungrounded question — that's a property of the draft, not the job. Check the draft's own flagged_reason once you fetch it.