add_respondents
ChatGPTAdds more respondents to a completed PickFu survey. respondentsAmount is the new TOTAL count (not the number to add) and must be one of PickFu's allowed package sizes — not an arbitrary number; the API returns the valid options if rejected. Set preview:false to charge credits and execute. Survey must be MTurk-sourced and completed within the last 120 days.
build_poll_url
ChatGPTGenerates a URL that creates a new PickFu survey with the specified parameters when opened. Supports demographic targeting, reporting segments, and various option formats (text, media URLs, ASINs, mockups). For a hypothetical/custom mockup without an image, call generate_image first and pass its returned image_url as mockup.image. For a survey with image options, pass previewImages: true to also get an inline preview of every image, labeled by question/option — show those to the user so they can confirm the correct assets are attached (and catch mistakes like two options sharing the same image) before launching. Pass questions as a FLAT array of { type, prompt, options } objects — do not double-nest it. Each option uses exactly ONE content type (value OR mediaUrl OR asin OR imageSet OR mockup). Example: { questions: [{ type: "head_to_head", prompt: "Which do you prefer?", options: [{ value: "A" }, { value: "B" }] }], targeting: ["amznpr"] }.
check_upload
ChatGPTCheck the status of a PickFu-hosted upload session minted by upload_media (no args). Returns {status: "pending"|"complete", files: [{media_url, filename, mime, bytes}]} in selection order. Call this after the user returns from the upload link so you can continue with the media-cdn.pickfu.com URLs.
create_tag
ChatGPTCreates a new tag for organizing PickFu surveys. Tags are scoped to your organization/account.
delete_survey
ChatGPTDeletes or archives a PickFu survey. Draft surveys are soft-deleted; published surveys are archived (data preserved). Idempotent.
discover_targeting
ChatGPTFinds ranked audience targeting matches from a country and free-text description. Use alongside list_available_targeting when the user describes an audience in words; fall back to list_available_targeting to browse the full catalog whenever the matches look wrong, the response carries low_confidence, or the query is not in English (trait labels are English-only in every country). The response includes ranked matches with scores, reasoning, and pricing, plus recommended audiences when available; present the JSON as returned and pass chosen permalink values to save_survey.targeting. time_expectation is null in this version.
export_survey_results
ChatGPTReturns download URLs for a completed survey's results in CSV, PDF, and PNG formats. Requires authentication and read scope; the caller must be able to view the survey. Use the format argument to limit which formats are returned, and the language argument (ISO 639-1 code) to filter PDF/PNG entries by language. CSV URLs include a short-lived signed token that lets MCP clients follow the link without supplying their own auth header. URLs are returned as resource_link content blocks the client can download or render directly.
generate_image
ChatGPTGenerate an image for PickFu research — either create a product image for a hypothetical/custom mockup or prepare creative variants of an existing product image, thumbnail, ad, or app-store asset for respondent testing and to put in front of respondents. For a mockup without an existing product image, call this tool first, then pass its returned image_url as mockup.image in save_survey or build_poll_url. Describe the image in the prompt, and optionally provide up to 3 existing reference images to adapt. For local files, call upload_media with no arguments to mint a PickFu upload link, then check_upload for media-cdn.pickfu.com URLs. Generating images is free — do not tell the user it costs anything. Uses Nano Banana Pro and returns the generated image URL in image_url.
generate_report
ChatGPTGenerate a PickFu report from a server template: the same report the app's Generate report button makes. Use template poll-summary with survey_id for one survey, or project-summary with project_id for every poll in a project. Offer it once a survey has finished collecting, or once every poll in a project has finished, and ask the user before calling, because it starts a long model run. Returns id, url and status straight away; status is PENDING and the report fills in at url over a few minutes. IMPORTANT: always present url as a clickable link. The report is private to the user until they share it from the report page. Each call starts a new report, so never retry automatically; after a timeout, check Reports before trying again. A survey that is still collecting, or a project with a poll still collecting, is refused. No credits are spent.
get_followup_answers
ChatGPTRetrieves the answers respondents provided to follow-up questions sent on a PickFu survey. Each item ties back to the original response by responseId, so you can correlate follow-ups with the source answer from get_survey_responses. Use response_id to filter to follow-ups for a single original response. Items where refunded=true indicate the follow-up was not delivered (e.g. the respondent declined or the request expired) and the credit was refunded.
get_playbook
ChatGPTReturns the full structured playbook for a given slug: its goal plus steps_markdown — a markdown guide whose steps contain pre-filled survey-creation URLs for the user to open (these links are user-facing, not inputs for save_survey).
get_project
ChatGPTGets a PickFu project by its unique ID. Returns project details including name, description, goal, survey count, and lightweight survey summaries.
get_report_writing_guide
ChatGPTGet the current report vocabulary and authorized teams before authoring a report. Use this read-only guide before write_report; it does not save a report or create a survey. Returns format_version, guidance, prose_example, limits, rendering_constraints, block schemas/examples, and team IDs/names. Present the relevant constraints and team choices. Use only returned blocks and team IDs, never invent them. JSON Schema does not describe every custom refinement. No report is written and no credits are spent.
get_survey
ChatGPTRetrieves a PickFu survey by ID, including metadata, questions, options, AI summaries, and all responses. The optional language selects stored translations; if the requested language is unavailable, the API returns the available languages instead of silently returning untranslated content. Each question includes a results summary with the final outcome — per-option vote counts, percentages, and ranking (winner first), matching the numbers on the results page; for ranked questions these reflect the human panel's final instant-runoff (IRV) round, not first-choice share. Compare with get_synthetic_feedback_results only after aligning the question, option identities, and audience; label each source and metric separately. Do not pool human and synthetic samples or treat their percentages as equivalent. results is null for open_ended, click_test, likert, five_second_test, and screen_recording, or before any responses arrive; emoji_rating/star_rating return an averageScore instead of per-option votes. For surveys with many responses, use get_survey_responses for pagination.
get_survey_responses
ChatGPTRetrieves responses for a PickFu survey, including explanations, chosen options, and respondent demographics. The optional language selects stored translated response explanations; if the requested language is unavailable, the API returns the available languages instead of silently returning untranslated content. Supports filtering by keyword (text) and respondent demographics (traits). When page is omitted, auto-fetches all pages (limit is ignored in this mode). Use get_survey for metadata and AI summaries. Use list_available_targeting for trait permalink values. To flag a specific response as helpful or not_helpful, pass its id to rate_response. Each response includes a pinned field — use pin_response to pin or unpin responses.
get_synthetic_feedback_results
ChatGPTFetches the results of a synthetic feedback request. Call this once with the guid — the call stays pending until status is COMPLETE (up to ~100 seconds) and streams live progress in supported clients. Do not call it repeatedly. If it ever returns while still IN_PROGRESS, call again with the same guid to resume. What a COMPLETE response carries depends on the research type. Comparison requests (head-to-head/ranked) return a summary with winner (the option the twins leaned toward, or null when the top options tied), options (each option's label and content), sampleReasons (short per-option quotes), and usually a narrative paragraph. Lead with the narrative: the themes behind the result, then which options fell in the stronger half and which in the weaker half. Without a narrative, give the direction from winner and sampleReasons. A null winner means the twins split evenly: say so, and do not pick a side. The summary carries no vote counts, percentages or mean ranks, on purpose: twins converge, so a synthetic margin overstates the real one. Never state, estimate or tally vote shares, vote counts, mean ranks or margins for a synthetic result, and never crown a winner with a margin. If the user needs the size of the gap, recommend a human survey. To set a synthetic result beside a human survey from get_survey, first align the question, option identities and audience, then compare direction only and label each source. Do not pool human and synthetic samples. Single-concept open-ended requests return a summary with the panel's themes and quotes for the one question asked. By default (individualAnswers omitted or false) you get only that summary. AFTER presenting it, you MUST tell the user they can drill into the raw per-respondent answers. If they say yes, call this tool again with the same guid and individualAnswers: true — that returns results (per-respondent Q&A, keyed by short anonymous segment_name ids) in place of summary. For a comparison, each answer is one twin's pick and reason: quote the reasons, but do not count the picks into shares. Do not return both in a single call. If the response has summary_status: "unavailable" (no summary field, no results field), the summary failed to generate for this run. Tell the user the summary is not available, then offer to fetch the per-respondent answers instead — if they say yes, call this tool again with the same guid and individualAnswers: true. Respondent ids quoted in an open-ended summary (respondent_id) match the segment_name strings in results, so quotes can be cross-referenced once the user asks for the drill-down. If a response carries next_step, it overrides the resume rule above: the run is still in progress and this turn is nearly out of time. Tell the user it is still running, and do not call this tool again in the same turn.
get_synthetic_playbook
ChatGPTDiscover and retrieve synthetic-research playbooks — self-contained, step-by-step instructions that orchestrate the synthetic-feedback tools (get_synthetic_feedback, generate_image, extract_images, etc.) into a repeatable research workflow. Two modes: • Call with NO arguments to LIST the available playbooks. Each comes back with an id, a user-facing title, and a description. Present the titles and descriptions to the user and ask which one they want to run. • Call again with playbook_id set to a listed id to FETCH that playbook's full instructions. STOP after this call: show the playbook to the user and get their explicit confirmation before you begin executing any of its steps. Do not chain straight into running the playbook without that approval. This is distinct from get_playbook/list_playbooks, which serve generic survey-sequence guides — use get_synthetic_playbook for the synthetic-research workflows.
get_template
ChatGPTGet one PickFu template, a ready-made single-question poll with a fixed price per respondent, by the cmb_ id from list_templates. Returns the summary fields plus question text with any blanks to fill, full constraints (question types, option types and counts, sample sizes, countries and defaults), option slots, audience (preset, choosable and blocked traits), reporting traits, context help and an example link. To run it, call save_survey with template: { id, blanks, options } within these constraints. The url opens it in PickFu's poll builder instead; present it as a clickable link. Read-only; does not publish or spend credits.
help_center_search
ChatGPTSearches PickFu help articles plus PickFu examples, case studies and solutions pages. Each result is labeled [Help], [Example], [Case study] or [Solution]. Pass types: ["help"] for policy, pricing, billing and how-to questions; quote policy only from [Help] results and cite the URL. If a mixed search returns no [Help] result, retry with types: ["help"]. Narrow types when the user asks for one kind.
list_available_reporting
ChatGPTReturns available demographic reporting traits with their permalinks, optionally filtered by country.
list_available_targeting
ChatGPTBrowse country-scoped audience targeting traits and exact permalinks before selecting targeting. Optional query is a case-insensitive substring of the English trait name or permalink, not semantic discovery; use discover_targeting for natural-language matching when available. Returns traits plus pagination (total matching traits, total_pages, has_more, next_page). Default limit 20, maximum 50. Follow next_page with the same country_code, query, and limit to recover all matches; omit query to browse the full catalog. No matches means broaden or remove query, not that the country has no targeting. Present exact returned labels and permalinks.
list_mockup_templates
ChatGPTList the mockup templates a text option can show instead of plain text, such as an iOS App Store product page. Each has lookupKey, name, category, displayField (the field the option's value fills, such as the app name), valuesSchema (JSON Schema for its values), sampleValues and importSources (stores that can fill it). Returns pagination (default 20, maximum 50); use page + 1 while pagination.hasMore is true. Call this before save_survey, then give every option of the question { value, mockup: { template: lookupKey, values } }, with values matching valuesSchema, or { value, mockup: { template: lookupKey, import: { source, id } } } to fill it from a store listing when importSources lists the store. For an Amazon product listing, use the Amazon mockup (image, title, price) instead. Read-only; does not publish or spend credits.
list_playbooks
ChatGPTLists available PickFu playbooks -- step-by-step research guides for common use cases. Returns name, slug, description, industry, and survey count. Use get_playbook(slug) for the full guide.
list_projects
ChatGPTLists projects that organize PickFu surveys into groups. Supports pagination and filtering by bookmarked or archived status.
list_surveys
ChatGPTLists PickFu surveys with optional filtering, sorting, and pagination. By default this returns recent team/account-wide surveys — for users on a team, results may include surveys created by any team member, not just the authenticated user. Set mine: true to restrict results to surveys created by the authenticated user. Returns survey metadata including name, status, type, sample size, response count, creator name, tags, projects, and a url field linking to the full results page.
list_synthetic_audiences
ChatGPTLists the synthetic audiences available for synthetic feedback, one subcategory at a time. A synthetic audience is a group of synthetic respondents; call it a synthetic audience, never a panel, because PickFu's human respondents are called panels. Call it without arguments first: it returns the subcategory index, which gives each subcategory's audience count and the slug of its general audience. Then call it with subcategory set to one name from the index: it returns that subcategory's synthetic audiences, each with its display name, slug, and a one-line description of its people. Use it when the user wants to see or change which synthetic audience answers their research. get_synthetic_feedback already suggests one automatically, so call this when the user wants a different one, or after a NO_MATCHING_PANEL response whose reason is no_matching_audience, audience_too_specific or unclear_brief, or that gives no reason. Present the choices to the user, let them choose, then call get_synthetic_feedback with the chosen slug as panel to create a new draft. Present that draft and obtain fresh approval before submitting; never change the audience while submitting an existing draft. When presenting the index in Slack or another chat client, preserve one Markdown bullet per subcategory on its own line; never combine subcategories with · separators.
list_synthetic_feedback
ChatGPTLists the calling user's prior synthetic feedback requests (newest first), returning each request's guid, brief description, status, and timestamps. Call this when the user references their earlier briefs / prior feedback or asks 'what have I run?', or to look up a guid before calling get_synthetic_feedback_results. Use the optional status filter to scope to DRAFT / IN_PROGRESS / COMPLETE; default limit is 50 (max 100).
list_tags
ChatGPTLists available tags for organizing PickFu surveys. Supports search filtering and pagination.
list_templates
ChatGPTList PickFu templates: ready-made single-question polls, each with a fixed price per respondent. Templates are not playbooks, which are multi-poll research plans. Filter by query, access, country or optionType. Returns id, name, description, access, questionTypes, optionCount, pricePerResponse (US dollars), url and pagination (default 20, maximum 50); use page + 1 while pagination.hasMore is true. pricePerResponse is the template price. get_template also returns originalPricePerResponse, set only on some templates; when set, it is the price without the template. Use get_template for one template's full constraints. To run one, call get_template for its blanks and limits, then save_survey with template: { id }. The url opens the template in PickFu's poll builder instead; present it as a clickable link and preserve ids exactly. Read-only; does not publish or spend credits.
lookup_listing
ChatGPTRead a product or app listing from its store by id or link: title, images (main image first), price and currency, rating, ratings count, description, and store-specific fields such as Amazon bullets. Each field carries the provider that filled it; a field the store did not return is absent. Use this when the user names a listing and you need what it shows, instead of fetching the web page, which misses details the store renders with JavaScript. Sources today: amazon (an ASIN or Amazon product link) and apple (an App Store link or app id). Omit source only when reference is a link whose host identifies the store; a bare id needs source. An Amazon listing's fields fill one result on the amazon-search mockup template (list_mockup_templates): title, image from images[0], price, rating, reviews from ratingsCount, prime as "yes" or "no", and bought_past_month from recentSales, as a values.competitors[] row or as the user's own product; save_survey's description gives the steps. It does not create a survey.
mcp_feedback
ChatGPTSubmit feedback, suggestions, or bug reports to the PickFu team. The report and authenticated user's identity are sent to PickFu's Linear workspace when configured, with Sentry used as a fallback. Do not include credentials, secrets, or unnecessary personal data. Use when encountering tool errors, confusing behavior, or when the user wants to suggest improvements.
mini_poll
ChatGPTCreate, update, or publish the authenticated account's plan-included daily mini-poll. This tool is available only on eligible plans, and teammates on the same plan share one daily allowance. Mini-polls always have exactly one question, five respondents, no audience targeting or caller-selected reporting, and no screen recording. Use action=create to make a draft, then read the draft GUID from the response field id. Use that exact value in the surveyId input for action=update and, only after the user explicitly confirms launch, action=publish. Publishing consumes today's mini-poll allowance. Returns id, status, and a clickable url.
pin_response
ChatGPTPins or unpins a response on a completed PickFu survey. Pinned responses are marked as particularly useful or insightful for easy retrieval. Use get_survey_responses to see current pin states. Returns the updated response ID and pin state.
publish_survey
ChatGPTPublishes a PickFu survey, making it live and starting response collection. Charges the survey cost to the user's account. On an image survey, verify the attached images with the user first — call save_survey with previewImages: true (or extract_images on the option image URLs) and show them the labeled previews, since a wrong or duplicated image cannot be fixed once the survey is live.
rate_response
ChatGPTMarks an individual respondent comment as helpful or not_helpful. Use this after get_survey_responses to programmatically curate response quality — e.g. flag low-effort or off-topic responses for downstream filtering. IMPORTANT: rating a response 'not_helpful' is destructive. It counts against a 10-flag-per-survey cap (returns an error when exceeded) and, when within the cap, auto-rejects the response (and, on multi-question surveys, all responses from the same respondent), recalculates the survey's valid-answer count, and may reopen a completed survey to collect replacement responses. Confirm with the user before applying 'not_helpful' to multiple responses in bulk. Switching a previous 'not_helpful' rating to 'helpful' records the new vote but does NOT un-reject the response that was auto-rejected by the prior flag. Re-rating without re-sending the comment field preserves the previous comment.
save_project
ChatGPTCreate or update a PickFu project. Omit id to create; include id to update. Only provided fields are changed.
save_survey
ChatGPTThe response also includes a completionEstimate object when the feature is enabled: bucket (SUPER_EASY, EASY, MEDIUM, HARD, or MAY_NOT_COMPLETE), estimatedMinutes (number or null), and status ('ready' or 'pending'). This reflects how quickly the selected audience is expected to fill. If bucket is MAY_NOT_COMPLETE, warn the user that the audience is too narrow and suggest broadening it. For sampleSize 5, 10, 20, or 25, include questions containing a screen_recording question, even on updates. Use get_survey to retrieve the existing questions and preserve their ids; without questions, only standard sample sizes (15, 30, 50, 75, 100, 200, 300, 500) are accepted. LIKERT: Use 2–8 text statements as options[].value, no media or URLs. The likertScale presets are agreement5, agreement7, frequency, satisfaction; agreement5 is the default on create, and omitting likertScale on an update preserves the question's existing scale rather than resetting it. TEMPLATES: to run a template (a ready-made single-question poll at a fixed price per respondent), call get_template first to read its question, blanks, option slots and limits, then create with template: { id, blanks?, prompt?, context?, options? } in place of questions. Template ids start with cmb_ and come from list_templates. Fill every {{name}} blank through blanks, keyed by its name; use prompt only on a template without blanks. Omitted name, sampleSize, country and targeting come from the template; targeting replaces the preset audience, so to change it send the template's preset traits plus your additions. reporting cannot be sent because a template's reporting traits are fixed. A draft outside the template's limits is rejected with every violation and its allowed values, and nothing is saved: fix each one and retry, or build the poll with questions at standard pricing. Template is create only; edit the draft afterwards with surveyId and questions. Create or update a PickFu survey. Omit surveyId to create; include surveyId to update. When updating questions, include 'id' fields (from get_survey) to update in-place — questions/options without 'id' are created as new, and those missing from the payload are removed. IMPORTANT: every response automatically includes a required written explanation from the respondent for every question type except screen_recording. Do NOT add a separate open_ended question to capture 'why' — it duplicates the built-in explanation and wastes a question slot (multi-question surveys are priced per question). Phrase the real question, and the explanation comes back on each response as the explanation field. The response includes a cost object with: amount (dollars), balance (dollars), currency, canPayWithBalance, quotedCreditsCost (post-discount credits after free credits), creditsCostSubtotal (pre-discount credits), discounts (credit-side [label, amountInCredits] tuples — amounts are in credits, 1 credit = $2, and subtract directly from creditsCostSubtotal), discountsMoney (dollar-side [label, '$X.XX'] tuples), and planRequired (plan tier name or null). Note: Some reporting traits are auto-injected as free defaults based on the user's plan (Basic plans: age-range, gender; Standard+ plans: age-range, gender, ethnicity, house-income, edu). The response includes a reportingDefaultsApplied array listing which traits were auto-added vs explicitly requested. OPTION SHAPE: each option carries exactly ONE content type — text (value), image/video (mediaUrl), Amazon product (asin), multiple images (imageSet), or a custom listing (mockup). Never combine them on one option; an image option is NOT given a text label (respondents see A, B, C…). For a hypothetical/custom mockup without an image, call generate_image first and pass its returned image_url as mockup.image. The one exception is a mockup template such as an App Store page: call list_mockup_templates, then give every option of the question { value, mockup: { template, values } }. When the template lists importSources, send `mockup.i…
stop_survey
ChatGPTStops a live PickFu survey. This is irreversible -- the survey will be marked as complete and no further responses will be collected.
submit_synthetic_feedback
ChatGPTDispatches an approved synthetic feedback request to the synthetic audience stored on the draft. Do NOT call this tool until you have presented the plan from get_synthetic_feedback to the user in chat — the selected audience plus the question (single-concept) or options (comparison) — and they have explicitly approved it; do not infer approval from silence or prior context. Pass the same guid; audience changes require a new get_synthetic_feedback draft and a new approval. Optionally pass questions when the user edited the question text (single-concept research has exactly one question). Optionally pass excludePollGuids when the request repeats existing PickFu surveys, for example in a benchmark replay. The response confirms dispatch with the request guid and status; present that confirmation, then call get_synthetic_feedback_results once with the same guid to retrieve the completed prediction. That call streams live progress and returns when the panel is COMPLETE (typically a few minutes). Do not call it repeatedly. Cost: free for this account until PickFu's new plans launch. If asked about future prices, point to https://www.pickfu.com/help/what-do-platform-credits-cost rather than quoting one.
upload_media
ChatGPTUpload an image or video to get a permanent CDN URL for use in PickFu surveys. Three modes: (1) pass a publicly accessible HTTPS url; (2) pass base64 data (images only — JPEG/PNG/GIF/WebP/BMP/TIFF/SVG, max 20 MB; videos must use url) — ONLY when the file exists on local disk you can read directly (CLI/IDE clients such as Claude Code or Cursor); (3) call with neither url nor data to mint a PickFu-hosted upload session. If the user ATTACHED the file in the chat, always use mode 3: chat attachments are not reliably accessible as raw bytes, and re-encoding or compressing them into base64 tool calls fails on payload limits — do not attempt it. Present the returned upload_url to the user, wait for them to return, then call check_upload with the returned token to receive ordered media-cdn.pickfu.com URLs and continue the original task. YouTube/Vimeo/Wistia URLs do not need uploading.
write_report
ChatGPTSave an authored CommonMark report unchanged, not a survey. First use get_report_writing_guide and select an explicit authorized team; use save_survey to create a survey. Returns id, url, status, share_mode, and format_version without the document body. IMPORTANT: always present url as a clickable link and report status and sharing. PRIVATE sharing is default; only raise it when the user asked to share. PUBLIC permits logged-out readers and requires explicit user permission and public_sharing_confirmed=true. Each call creates a new report. Never retry automatically. After a timeout or abort, the report may have been saved; check Reports before retrying. No credits are spent. No server review or rewriting occurs.