All docs
21 min read Last updated:

Tools

Every tool checks the token's abilities before running; missing the ability returns a refusal. The tables below cover the complete workspace surface area registered on the server (116 tools).

Plan visibility

tools/list, resources/list, and prompts/list are filtered by the authenticated team's plan. On Free, survey, funnel, webhook, and AI tools (and their matching resources/prompts) are omitted entirely - clients that only read the list will not see them. On Pro and above, the full catalogue is returned.

You can still mint token abilities for paid products on any plan; without the plan feature, those tools either never appear in the list or refuse at call time with a plan error.

Plan MCP products available
Free Forms, submissions, links, automations, billing (read-only), tokens, framework catalog
Pro and above Everything in Free + webhooks, surveys, funnels, AI insights

Product routing

  • Forms - single-screen contact-style forms. Use create_form, not create_survey.
  • Surveys - multi-screen questionnaires, quizzes, NPS. Use create_survey, not create_form.
  • Funnels - multi-step lead-gen with screens, blocks, scoring, pixels, CAPI. Use create_funnel.
  • Links - branded short links and QR codes on every plan.

Call list_templates with product (form, survey, or funnel) before create_* when the user wants a starter. Pass the returned key as template on create_form, create_survey, or create_funnel.

Build a complete form, survey, or funnel in one call

set_form_document, set_survey_document, and set_funnel_document are the full authoring path. Each one builds a complete, styled product end-to-end from a single builder document - every field/question type, content blocks, conditional branching, welcome and ending screens, and styling - the same structure the visual builder saves. Prefer them over update_* (or add_screen / add_block) when you are laying out or restyling a product rather than patching one attribute.

Each create_* returns a public_id; pass it as form_id, survey_id, or funnel_id. Pass publish: true to make the result live in the same call.

Document shape

json
{
  "builder": { "name": "Q4 NPS", "settings": { "display_mode": "one_per_screen", "progress": "bar" } },
  "blocks": [ /* ordered screens / questions / content - see below */ ],
  "theme_v2": { "tokens": { "color": { "primary": "#4f46e5" } } }
}
  • builder - the product name plus product-level settings (e.g. survey display_mode / progress).
  • blocks[] - the ordered content. Each block has an id, a kind, and a position. A question block carries one or more elements (the input fields / content). welcome, ending_screen, and ending_redirect blocks carry their copy in config. Ids and per-element config defaults are filled in when omitted.
  • theme_v2 - the unified styling envelope (colors, fonts, radius, spacing, …) under tokens. This is the canonical styling surface and round-trips with the visual Styling editor. update_* accepts the same theme_v2 when you only want to restyle.

Element vocabulary

The type on each element reaches the full builder palette:

open_text, multiple_choice_single, multiple_choice_multi, picture_selection, ranking, consent, file_upload, rating, nps, csat, ces, matrix, contact_info, cal, cta, timeslots, date, barcode, range_slider

Content blocks render without collecting a submission key: heading, paragraph (a statement, not a textarea input), html, divider. (A typed email input is an open_text element with config.format: "email".)

  • Forms and surveys reject an unmapped type with a clear error (so a typo never silently drops a field).
  • Funnels never reject an unmapped type. Any type with no native funnel block (nps, matrix, csat, …) degrades loss-free to an inert html block that preserves the original type, so layout and styling always save. Funnel screens that stack several inputs or advance buttons are auto-split one step per screen.

Conditional branching (logic)

Attach a logic rule graph to any question block to branch on an answer. then.action is goto / skip / next, and then.target is the id of the block to jump to (rewritten internally to the right screen):

json
"logic": {
  "rules": [
    { "when": { "op": "and", "conditions": [ { "field": "score", "op": "lte", "value": 6 } ] },
      "then": { "action": "goto", "target": "blk_reason" } }
  ],
  "fallback": { "action": "next" }
}

Branching round-trips: re-saving a survey or funnel preserves the rules so a later edit never drops a jump.

Welcome and ending screens carry a body

Welcome and ending screens now support a multi-paragraph body alongside the headline and button_label. Author it with newline-separated paragraphs; the hosted page renders and themes each paragraph.

json
{ "id": "blk_welcome", "kind": "welcome", "position": 0,
  "config": { "headline": "Hi there", "body": "Two minutes, promise.\n\nNo wrong answers.", "button_label": "Start" } }

Example: a survey with NPS, a branch, and a welcome body

json
set_survey_document {
  "survey_id": "sv_8Qd2",
  "publish": true,
  "document": {
    "builder": { "name": "Q4 NPS", "settings": { "display_mode": "one_per_screen", "progress": "bar" } },
    "blocks": [
      { "id": "blk_welcome", "kind": "welcome", "position": 0,
        "config": { "headline": "Hi there", "body": "Two minutes, promise.\n\nNo wrong answers.", "button_label": "Start" } },
      { "id": "blk_nps", "kind": "question", "position": 1,
        "logic": { "rules": [ { "when": { "op": "and", "conditions": [ { "field": "score", "op": "lte", "value": 6 } ] }, "then": { "action": "goto", "target": "blk_reason" } } ], "fallback": { "action": "next" } },
        "elements": [ { "type": "nps", "name": "score", "config": { "label": "How likely are you to recommend us?" } } ] },
      { "id": "blk_reason", "kind": "question", "position": 2,
        "elements": [ { "type": "open_text", "name": "reason", "config": { "label": "What went wrong?", "long": true } } ] },
      { "id": "blk_email", "kind": "question", "position": 3,
        "elements": [ { "type": "open_text", "name": "email", "config": { "label": "Email", "format": "email", "save_as_contact": true } } ] },
      { "id": "blk_end", "kind": "ending_screen", "position": 4,
        "config": { "headline": "Thanks!", "body": "We appreciate it." } }
    ],
    "theme_v2": { "tokens": { "color": { "primary": "#4f46e5" } } }
  }
}

Example: a styled form in one call

json
set_form_document {
  "form_id": "r2EdO-orF-3S",
  "document": {
    "builder": { "name": "Contact" },
    "blocks": [
      { "id": "blk_welcome", "kind": "welcome", "position": 0, "config": { "headline": "Get in touch", "body": "We reply within a day." } },
      { "id": "blk_q", "kind": "question", "position": 1, "elements": [
        { "type": "heading", "config": { "text": "Your details", "level": "h2" } },
        { "type": "open_text", "name": "full_name", "config": { "label": "Full name", "required": true } },
        { "type": "open_text", "name": "email", "config": { "label": "Email", "format": "email", "required": true } },
        { "type": "rating", "name": "satisfaction", "config": { "label": "How was it?" } }
      ] },
      { "id": "blk_end", "kind": "ending_screen", "position": 2, "config": { "headline": "Thanks!" } }
    ],
    "theme_v2": { "tokens": { "color": { "primary": "#0ea5e9" } } }
  }
}

Example: a funnel - one block per screen

A funnel document uses one block per screen (a step); each screen's fields/content are its elements. Unmapped types degrade to html rather than failing.

json
set_funnel_document {
  "funnel_id": "fn_lead_quiz",
  "document": {
    "builder": { "name": "Lead quiz" },
    "blocks": [
      { "id": "blk_welcome", "kind": "welcome", "position": 0, "config": { "headline": "Find your plan", "body": "60 seconds." } },
      { "id": "blk_goal", "kind": "question", "position": 1,
        "logic": { "rules": [ { "when": { "op": "and", "conditions": [ { "field": "goal", "op": "equals", "value": "pro" } ] }, "then": { "action": "goto", "target": "blk_pro" } } ], "fallback": { "action": "next" } },
        "elements": [
          { "type": "heading", "config": { "text": "What's your goal?", "level": "h2" } },
          { "type": "multiple_choice_single", "name": "goal", "config": { "label": "Goal", "options": [ { "value": "starter", "label": "Starter" }, { "value": "pro", "label": "Pro" } ] } },
          { "type": "cta", "config": { "button_text": "Continue" } }
        ] },
      { "id": "blk_pro", "kind": "question", "position": 2,
        "elements": [ { "type": "open_text", "name": "email", "config": { "label": "Work email", "format": "email", "required": true } } ] },
      { "id": "blk_end", "kind": "ending_screen", "position": 3, "config": { "headline": "Thanks!" } }
    ],
    "theme_v2": { "tokens": { "color": { "primary": "#7c3aed" } } }
  }
}

Per-entity captcha, scoring, and notifications

update_form, update_survey, and update_funnel now also set the surrounding configuration the document does not own:

  • Captcha is always per-entity, never global. Set hcaptcha_enabled / recaptcha_enabled plus the matching *_site_key / *_secret on the individual form, survey, or funnel. Leaving a secret empty keeps the existing key so an unrelated edit never wipes stored credentials.
  • Scoring (scoring), hidden fields (hidden_fields, captured from URL params), notification emails (notification_emails), autoresponder (autoresponder), redirect (redirect_url), and the spam honeypot (honeypot_field).

Templates

Tool Ability Description
list_templates forms:read (form), surveys:read (survey), funnels:read (funnel) List starter templates; optional category and search filters. Survey and funnel products require a paid plan.

Forms

Tool Ability Description
list_forms forms:read List active forms in the team
get_form forms:read Fetch one form by public_id
create_form forms:write Create a new form (optional template key from list_templates)
update_form forms:write Patch name, slug, a full builder document (all field + content types + theme + welcome/ending), legacy fields, theme, settings, notification emails, autoresponder, redirect, honeypot, and per-form captcha
set_form_document forms:write Build a complete, styled form in one call from a builder document. See Build in one call
publish_form forms:write Set published_at = now()
unpublish_form forms:write Clear published_at
archive_form forms:write Soft-delete
restore_form forms:write Reverse archive
send_test_autoresponder forms:test-email Send preview autoresponder to your account email
send_test_notification forms:test-email Send preview owner-notification

Submissions

Tool Ability Description
list_submissions submissions:read Paginate, filter by folder
get_submission submissions:read Fetch one with files
update_submission submissions:write Patch payload or status
delete_submission submissions:write Permanent delete + file cleanup
bulk_submissions submissions:write Up to 500 ids: delete, mark_spam, mark_not_spam
export_submissions submissions:export Inline JSON, up to 500 rows
get_submission_file submissions:read Short-TTL signed URL
mark_as_spam submissions:write Quick mark with reason manual:mcp
get_form_stats submissions:read 30-day totals, spam ratio, AI score average

Webhooks

Tool Ability Description
list_webhooks webhooks:read Webhooks for a form, with delivery counts
get_webhook webhooks:read Single webhook (no secret)
create_webhook webhooks:write Returns plaintext signing secret ONCE
update_webhook webhooks:write URL, label, active flag
delete_webhook webhooks:write Remove
list_webhook_deliveries webhooks:read Last 50 (configurable up to 200)
replay_webhook_delivery webhooks:write Re-dispatch a previous delivery

Surveys

Surveys are a separate product from Forms - multi-screen questionnaires, quizzes, and NPS flows with conditional logic. Never call create_form to make a survey, or create_survey to make a contact form. All survey tools require a paid plan.

Tool Ability Description
list_surveys surveys:read List surveys belonging to the current team
get_survey surveys:read Fetch a single survey by public_id
create_survey surveys:write Create a new survey (optionally from a template)
update_survey surveys:write Update name, slug, redirect, a full builder document (all question types + branching logic + theme + welcome/ending), legacy fields, theme, settings, scoring, hidden fields, notification emails, autoresponder, and per-survey captcha
set_survey_document surveys:write Build a complete, styled survey - questions, branching, theme - in one call from a builder document. See Build in one call
publish_survey surveys:write Publish - make the survey live and respondable
unpublish_survey surveys:write Return to draft, stop accepting responses
delete_survey surveys:write Soft-delete (recoverable from the dashboard)
get_survey_insights insights:read Read open-text AI insights (summary, sentiment, theme clustering) for a survey; returns { locked: true } when the plan lacks AI features
regenerate_survey_insights insights:write Queue regeneration of a survey's open-text AI insights; optionally limit to one question by submission key. Idempotency-locked for 5 minutes

Surveys capture CRM contacts from responses. A survey mints a contact whenever it has at least one typed email question. Capture is opt-in per email question via save_as_contact, which defaults on - set it false on a specific question (e.g. "your colleague's email") to opt that one out. Identity is read only from typed email / phone questions, never by scanning free-text answers. Set save_as_contact in the element config when building with set_survey_document.

Action classes

Action classes are the triggers that decide when an in-app or website survey fires - a code action fires from an SDK track(key) call, a noCode action auto-fires from a spec (page view, click, exit intent, scroll depth, dwell, with optional URL filters). A survey fires when any of its attached triggers fires. Part of the in-app / website survey suite; requires a paid plan.

Tool Ability Description
list_action_classes action-classes:read List action classes (survey triggers) for the current team
get_action_class action-classes:read Fetch a single action class by public_id
create_action_class action-classes:write Create a trigger; code actions fire from an SDK track(key) call, noCode actions auto-fire from a no_code_config spec (page view / click / exit intent / scroll / dwell with optional URL filters)
update_action_class action-classes:write Update name, description, type, key, or no_code_config; partial payloads are last-write-wins
delete_action_class action-classes:write Delete a trigger and its survey-trigger links; surveys simply stop firing on it. Queued
attach_survey_trigger action-classes:write Attach a trigger to a survey (idempotent)
detach_survey_trigger action-classes:write Detach a trigger from a survey (idempotent)

Contacts

The CRM audience captured from in-app / website survey responses (and managed directly). A contact is identified by external_user_id and/or email; attributes merge last-write-wins. Requires a paid plan.

Tool Ability Description
list_contacts contacts:read List contacts belonging to the current team
get_contact contacts:read Fetch a single contact by public_id, including its merged attributes
create_contact contacts:write Create or upsert a contact (identified by external_user_id and/or email; attributes are merged)
update_contact contacts:write Backfill identity (email / external_user_id) and merge attributes (last-write-wins)
delete_contact contacts:write Erase a contact and its attributes; survey responses are de-identified, not deleted. Queued

Segments

Segments are reusable survey audiences: each owns a recursive AND/OR filters tree over contact attributes, device class, and nested segment membership. A survey targets one segment. Part of the in-app / website survey suite; requires a paid plan.

Tool Ability Description
list_segments segments:read List segments (survey audiences) for the current team
get_segment segments:read Fetch a single segment by public_id
create_segment segments:write Create a segment with a recursive AND/OR filters tree over contact attributes, device class, and nested segment membership
update_segment segments:write Update title, description, privacy, or filters; partial payloads are last-write-wins
delete_segment segments:write Delete a segment; any survey targeting it becomes unsegmented (shows to everyone). Queued
assign_survey_segment segments:write Set a segment as a survey's audience (a survey targets one segment)
unassign_survey_segment segments:write Clear a survey's audience segment (it becomes unsegmented and shows to everyone)

SDK keys

Public environment keys the in-app / website survey SDK embeds in the browser. Each key carries an allowed_origins CORS allow-list - an empty list denies all cross-origin browser use, so add your production origins explicitly. Part of the in-app / website survey suite; requires a paid plan.

Tool Ability Description
list_sdk_keys sdk-keys:read List the team's public SDK keys
get_sdk_key sdk-keys:read Fetch a single SDK key by its public key value
create_sdk_key sdk-keys:write Mint a new public SDK key; allowed_origins is a CORS allow-list and an empty list denies all cross-origin use
update_sdk_key sdk-keys:write Rename, replace the allowed_origins CORS list, or toggle is_active; passing allowed_origins replaces the whole list (empty array denies all cross-origin use)
revoke_sdk_key sdk-keys:write Deactivate the key (rejected immediately) and soft-delete it; historical displays/responses are preserved. Queued

Displays (read-only)

Read-only analytics over survey displays / impressions captured by the SDK. Part of the in-app / website survey suite; requires a paid plan.

Tool Ability Description
list_displays displays:read List survey displays / impressions; optionally filter by survey_id and unresponded-only
get_display displays:read Fetch a single display / impression by public_id
get_survey_display_analytics displays:read Display-funnel analytics for a survey - completion rate, per-question drop-off, time-to-complete; optional date range and segment / contact-attribute filter

Funnels

Funnels are multi-step lead-gen / quiz funnels with screens, blocks, scoring, pixels, A/B tests, and server-side CAPI. All funnel tools require a paid plan. Funnel tools accept either public_id (preferred, mirrors forms/surveys) or the legacy slug to identify a funnel.

Tool Ability Description
list_funnels funnels:read List funnels for the current team
get_funnel funnels:read Get a funnel by public_id (preferred) or slug
create_funnel funnels:write Create a blank funnel or hydrate a gallery template via template
update_funnel funnels:write Update top-level config and replace screens. Sets theme / theme_v2 styling, tracking pixels, A/B config, autoresponder, notification emails, honeypot, hidden fields, allowed origins, and a full ordered screens array (id-diff upsert)
set_funnel_document funnels:write Build a complete, styled multi-step funnel - screens, blocks, branching, theme - in one call from a builder document. See Build in one call
publish_funnel funnels:publish Publish or unpublish a funnel
delete_funnel funnels:write Soft-delete (recoverable)
get_funnel_analytics funnels:analytics Funnel analytics summary
list_funnel_sessions funnels:analytics Recent sessions for a funnel
add_screen funnels:write Add a screen to a funnel
add_block funnels:write Add a block to a funnel screen
set_logic funnels:write Attach an AND/OR DSL logic rule to a block
set_score funnels:write Attach a per-block score map (bucket → points)
set_pixel funnels:write Set browser-side pixel IDs (GA4 / GTM / Meta / TikTok / LinkedIn / Pinterest / Snap / Bing / Reddit / Twitter)
set_capi_token funnels:write Configure server-side CAPI credentials for a vendor (meta / tiktok / linkedin / pinterest)

Links

Branded short links and QR codes. Available on every plan.

Tool Ability Description
list_links links:read List short links for the current team
get_link links:read Fetch one short link by id or slug
create_link links:write Create a new short link
update_link links:write Update an existing short link
delete_link links:write Soft-delete a short link

Bio pages

A Bio page is a single public link-in-bio profile (handle, avatar, headline, bio) listing many ordered blocks. It is not a form, survey, funnel, or single link - use these tools, never create_form / create_survey / create_funnel / create_link. Requires a plan that includes Bio Pages.

Tool Ability Description
list_bio_pages bio:read List link-in-bio profile pages for the current team
get_bio_page bio:read Fetch one page by id or handle, including its blocks
create_bio_page bio:write Create a new profile page (a single public page listing many blocks)
update_bio_page bio:write Update the page profile and publish state
set_bio_document bio:write Build or restyle an entire bio page from a builder document (all block types + theme), replacing the page's blocks in one call
set_bio_pixel bio:write Set one browser-side tracking pixel ID on a page (GA4 / GTM / Meta / TikTok)
add_bio_block bio:write Append or insert one content block (link, header, text, social, embed, image, form, …) onto a page
reorder_bio_blocks bio:write Reorder a page's blocks by id
delete_bio_block bio:write Remove a single block (cascades its managed short link / files)
delete_bio_page bio:write Delete a page; disabled immediately, hard delete queued

Automations

Per-form automation rules with steps that fire on submission events. Available on every plan. Use list_automations with a form's public_id; the team-wide formspring://team/automations resource lists automations across forms, surveys, and funnels.

Tool Ability Description
list_automations automations:read List automations for a form (form_id = form public_id)
get_automation automations:read Get a single automation with its steps
create_automation automations:write Create a new automation
update_automation automations:write Update top-level fields (steps via dedicated tools)
enable_automation automations:write Enable an automation
disable_automation automations:write Disable an automation
delete_automation automations:write Permanent delete (with steps + runs)
run_automation automations:run Manually trigger an automation
list_automation_runs automations:read List recent runs
get_automation_run automations:read Get one run with per-step outputs
replay_automation_run automations:run Replay a previous run

Billing (read-only)

Tool Ability Description
get_team billing:read Current team summary
get_plan billing:read Plan key, features, limits
get_usage billing:read Current period: submissions, storage, deliveries
get_subscription_state billing:read active / on_trial / on_grace_period / past_due / canceled

AI Insights

Tool Ability Description
get_ai_insights insights:read Insights payload (or { locked: true })
regenerate_ai_insights insights:write Trigger regen; locked 5 min between calls

Tokens (self-management)

Tool Ability Description
list_tokens tokens:read Your own tokens
create_token tokens:write Mint a token; abilities ⊆ caller's
revoke_token tokens:write Revoke (refuses on the active token)

Integration reference

Tool Ability Description
get_framework_integration_catalog forms:read Returns a maximum-breadth matrix of stacks (React, Next.js, Laravel, WordPress, mobile, serverless, …): each row includes a short copy-paste snippet (placeholder FORMSPRING_ENDPOINT → your https://…/f/{public_id}), notes (CORS, hosted vs legacy payloads, etc.), docs_url into this site's /docs/…, and optional recipe_slug when a long-form recipe exists. Supports optional category (spa, ssr, static, mobile, backend, cms, edge) and pagination page / per_page (max 100 per page). Deep guides remain on the docs site; MCP returns the compact matrix.

Example call

text
get_framework_integration_catalog {
  "category": "ssr",
  "page": 1,
  "per_page": 25
}

Example call

text
list_submissions {
  form_id: "r2EdO-orF-3S",
  folder: "spam",
  limit: 25
}

returns

json
{
  "submissions": [
    {
      "id": "01HFXX0X9R7KZJVN9VS6TG2C5T",
      "status": "spam",
      "spam_reason": "akismet",
      "ai_moderation_score": 87,
      "payload": { "email": "spam@bad.com", "message": "..." },
      "created_at": "2026-05-07T16:09:10Z"
    }
  ]
}

What's next