BETA
Skip to content

AI features ​

Krafter Surveys ships four AI-powered surfaces, each backed by the platform's LLM engine. Use them for the parts where humans don't add value — drafting questions, reviewing for clarity, picking the next adaptive question, summarising results.

FeatureUsed bySurface
Generate questionsYou — when authoring a surveyPOST /surveys/:id/generate
Review questionsYou — before launchingPOST /surveys/:id/review
Adaptive conversationRespondents — mode: "ai" surveysPOST /surveys/:slug/next
SummariesYou — after collecting responsesPOST /surveys/:id/summary, GET /summary

All four require the platform's LLM engine to be configured. If it isn't, the endpoints return 503 Service Unavailable. Transient upstream model failures return 502 Bad Gateway — retry with the same arguments.


Manual mode vs AI mode ​

Every survey is either manual or ai. The choice affects how respondents experience the survey:

manualai
Who picks the next question?You — by question position and branching rulesThe AI engine, per respondent, based on prior answers
Are branching rules respected?YesNo — the conductor ignores them
Are questions rendered to the respondent?Yes — in position orderNo — the AI generates each question on the fly
What's saved?answers keyed by question_idai_conversation array of {role, question, answer} turns + ai_cost_cents
Where does the next question come from?The survey's question listPOST /surveys/:slug/next

You can switch a survey between modes via PATCH /surveys/:id. Switching from manual to ai does not delete your authored questions — they remain on the survey and can be inspected via GET /surveys/:id, but the conductor won't use them.


Generating draft questions ​

Use POST /surveys/:id/generate to draft a question list for a goal. The endpoint returns candidate questions — it does not save them. Review the output, then create each question via POST /surveys/:id/questions.

bash
curl -X POST https://app.krafter.dev/api/v1/surveys/SURVEY_ID/generate \
  -H "Authorization: Bearer kr_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "goal": "Understand why new signups churn before week 2",
    "context": {
      "audience": "self-serve SaaS users",
      "tone": "casual",
      "language": "en",
      "max_questions": 6
    }
  }'

context fields ​

FieldDescription
topicSurvey topic (e.g. "onboarding", "pricing")
audienceWho the respondents are
tone"formal", "casual", etc.
languageLanguage code ("en", "es", "de", ...)
max_questionsSoft cap on the returned list length

All fields are optional. The engine uses sensible defaults from the survey's name and ai_config if you omit them.

The returned shape matches what POST /surveys/:id/questions accepts. Loop through the array, add a position, and persist:

bash
position=1
for question in "${questions[@]}"; do
  curl -X POST .../surveys/$SURVEY_ID/questions \
    -d "$(jq -n --argjson q "$question" --arg p "$position" '$q + {position: ($p|tonumber)}')"
  ((position++))
done

Reviewing existing questions ​

Once you've authored questions (manually or by saving the AI's drafts), use POST /surveys/:id/review to run them through a quality check. The reviewer flags:

  • Leading or biased phrasings
  • Double-barrelled questions (two asks in one)
  • Redundancy across questions
  • Confusing answer options
  • Ordering / flow issues

The endpoint does not edit anything — it returns suggestions for you to apply manually via PATCH /questions/:id.

json
{
  "data": [
    {
      "question_id": "q1c2d3e4-...",
      "issue": "leading",
      "severity": "warning",
      "message": "\"How great was our onboarding?\" presupposes the answer is positive.",
      "suggested_title": "How would you describe your onboarding experience?"
    }
  ]
}

The exact suggestion shape is owned by the AI engine and may evolve. Render unknown keys as plain text.


Adaptive AI surveys ​

Setting mode: "ai" on a survey makes the experience conversational — the AI engine asks one question at a time, branching based on the respondent's prior answers. The engine decides when there are no more useful questions to ask.

Authoring an AI survey ​

You don't author questions for AI surveys. Instead, you set the engine's brief in ai_config:

bash
curl -X PATCH https://app.krafter.dev/api/v1/surveys/SURVEY_ID \
  -H "Authorization: Bearer kr_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "ai",
    "ai_config": {
      "goal": "Understand why this user signed up",
      "target_questions": 5,
      "tone": "casual",
      "language": "en"
    }
  }'
ai_config fieldDescription
goalWhat the survey should learn. Required for AI mode
target_questionsSoft cap on conversation length
tone"formal", "casual", etc.
languageLanguage code
audienceTarget persona description

You can additionally seed the conversation with a "warmup" question authored manually — the AI will pick it up from questions[0] if present.

Respondent flow (AI mode) ​

The embed widget and standalone survey page handle this automatically. If you're rendering the survey yourself, the loop is:

  1. Start a response — POST /api/v1/surveys/:slug/responses (same as manual mode)

  2. Ask the AI for the next question — POST /api/v1/surveys/:slug/next with the running conversation array:

    json
    {
      "conversation": [
        {"role": "ai", "question": "What did you build with Krafter?"},
        {"role": "user", "answer": "A signup form"}
      ]
    }
  3. Render the question, capture the answer, append to conversation, repeat step 2.

  4. Save progress via PATCH /api/v1/surveys/:slug/responses/:response_id — pass the full ai_conversation array. The response's ai_cost_cents is updated server-side

  5. When done: true comes back from /next, call POST /complete

The data shape from /next:

json
// More questions to come
{
  "data": {
    "question": "How long did the form take to set up?",
    "type": "text",
    "done": false
  }
}

// Conversation is complete
{
  "data": {
    "summary": "User successfully built a signup form in under 10 minutes.",
    "done": true
  }
}

Cost ​

AI conversations call an LLM on every /next, so total cost scales with conversation length and answer verbosity. Each response's ai_cost_cents field accrues the running token cost — surface it on the dashboard if you want per-response cost visibility.


Response summaries ​

Once you have enough completed responses, summarise them:

  1. Enqueue a job — POST /surveys/:id/summary. Returns 202 Accepted immediately
  2. Wait for completion — either subscribe to the summary.generated webhook or poll GET /surveys/:id/summary
  3. Read the summary — text overview, bullet insights, response tags, confidence

Summaries run a single LLM call against the completed responses for the survey. Cost scales with response count and answer length. The dashboard rate-limits regenerations; if you generate programmatically, throttle.

The latest summary is what GET /surveys/:id/summary returns. Older summaries are retained in the database (for the audit trail) but not exposed via the API today.

See Analytics → Summary for the full schema.


When the engine isn't configured ​

If the LLM backend isn't wired up — no API key, model unreachable — the four AI endpoints return 503 Service Unavailable with {"error": "AI engine not configured"}. The platform operator (typically the team running the Krafter installation) is responsible for provisioning the LLM provider. On the hosted app.krafter.dev deployment, this is always configured.

For self-hosting, see the self-hosting guides — the AI engine is opt-in, and surveys gracefully degrade to manual mode without it (the manual-mode flow does not depend on the engine at all).


Privacy considerations ​

AI features send respondent answers (and, for review, your question text) to the configured LLM provider. If you handle answers covered by data-handling agreements (PII, medical, financial), confirm with your provider that:

  • Your account is on a no-training tier
  • Inputs are not retained beyond the request lifetime
  • The data residency of the provider matches your jurisdiction

The Krafter platform does not redact PII before sending — it forwards answers as-is. If you need to redact, do it on your side before saving via save_progress, or stick to manual surveys.

Built by Krafter Studio