- Brand
- FormHug
- Category
- Productivity
- Primary Subcategory
- Form & Survey Builders
Integration details
Description
Create forms for registrations, surveys, quizzes, assessments, and bookings inside ChatGPT. Describe what you need in natural language, and FormHug generates a complete form with fields, descriptions, logic, and layout. You can refine forms through conversation, customize themes, publish forms, collect submissions, and analyze responses — all in the same chat. FormHug helps turn everyday data collection into a simple conversational workflow.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Form & Survey Builders
- Secondary Subcategories
- None listed
- Brand
- FormHug
- Access
- Account required
- First tracked
- 2026-06-17
- Tool count
- 47
- Market
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your score is coming
ChatGPT now suggests Plugins on its own when they match a user's request.Your Plugin Discovery Score measures how often yours appears, and it will show here as soon as it’s ready.
What discovery looks like

Get alerts for FormHug
Get updates when FormHug’s Discoverability Score or category rank changes.
Competing in ChatGPT Form & Survey Builders
View Category47 tools agents can invoke
If you have not read `formhug://guide` this session, read it first. Add one or more fields to an existing form. By default they are appended to the end in order; give a field a `before` / `after` anchor (an **existing** field's api_code) to insert it immediately before / after that field. All placements apply in a single update, so the saved result is atomically valid. Each field is an object with a snake_case `type` and a `label`. Use `type` from this exact list: - Basic: `short_text`, `long_text`, `radio`, `checkbox`, `image_radio`, `image_checkbox`, `dropdown`, `number`, `email`, `phone`, `date`, `name`, `url`, `address`, `rating`, `nps`, `attachment`, `audio`, `signature`, `ranking`, `time`, `location` - Advanced: `cascade`, `matrix`, `matrix_rating`, `likert`, `table`, `product`, `booking`, `linked_form`, `formula` - Display-only (collect no input): `page_break`, `description` Choice fields (`radio`, `checkbox`, `dropdown`) take `choices` as an **array of objects**, not strings — one per option, each `{label, ...}`. Example: ```json {"type": "radio", "label": "How did you hear about us?", "choices": [{"label": "Friend"}, {"label": "Other", "is_other": true}]} ``` `page_break` starts a new page at its position; its `label`/`notes` render as that page's heading. For choice free-text roles (`is_other` / `allow_extended_text`), advanced-field shapes and per-type keys, see `formhug://field-types`; for `api_code` rules, see `formhug://guide`. For Quiz/Assessment forms, new fields may include `answers` / `answer_explanation` (same shape as `create_form`); see the guide on following up about score-based feedbacks. This tool re-sends the form's existing fields with their api_codes so they are preserved. If this form uses conditional logic (fields that show/hide based on answers, or post-submission redirects), use `get_field_rules` / `update_field_rules` to keep the rules in sync — adding, removing, reordering, or rechoicing rule-referenced fields can invalidate trigger/target api_codes. See `formhug://field-rules`.
add_fields
Finalize prepared `rich_text_image` uploads into stored images, returning each image's public `image_url` (same order as `upload_ids`). Embed the URLs as `<img src="<image_url>">` in rich-text HTML — form `description`, field `notes`, `after_submission.show_message.rich_text`, or report feedback `comment`. Flow: 1. `prepare_image_upload` with purpose `rich_text_image` (one call per image). 2. `PUT` each file's bytes to its `upload_url`. 3. Call this tool with the `upload_ids` (1-20 per call). 4. Write the returned `image_url`s into the HTML you pass to create_form / update_form / update_fields / update_form_settings. All-or-nothing: if any entry is invalid the whole request fails (422 with per-entry `error_details`) and nothing is consumed. Already-processed entries are remembered, so retrying with the same `upload_ids` does not create duplicates.
commit_rich_text_images
Create up to 200 entries in one call on a form the user owns or collaborates on — e.g. importing rows from a spreadsheet. Each item's `field_values` takes the same shapes as `submit_entry` (see `formhug://entry-values`). Each item is validated on its own: valid items are created, invalid ones come back in `failed` by their `index` in `entries` (with `error_details`). Check `failed` and fix or report those items; do not resend the ones in `succeeded`. Behaves like a data import: no new-entry notifications, webhooks or integrations are triggered. To submit a single entry as a respondent would (with notifications), or to a published form the user does not own, use `submit_entry`. `booking` and `product` values are not taken here: such items come back in `failed`; submit them one by one with `submit_entry`. If the rows are per-person records others should look up themselves (scores, results, order status), offer a public lookup page via `create_public_query` afterwards (see the guide's Public Queries section).
create_entries
Create a new folder. By default the folder is created at the top level (desktop). Pass parent_folder_token to nest it under another folder.
create_folder
If you have not read `formhug://guide` this session, read it first. Create a new form. Each field is an object with a snake_case `type` and a `label`. Use `type` from this exact list: - Basic: `short_text`, `long_text`, `radio`, `checkbox`, `image_radio`, `image_checkbox`, `dropdown`, `number`, `email`, `phone`, `date`, `name`, `url`, `address`, `rating`, `nps`, `attachment`, `audio`, `signature`, `ranking`, `time`, `location` - Advanced: `cascade`, `matrix`, `matrix_rating`, `likert`, `table`, `product`, `booking`, `linked_form`, `formula` - Display-only (collect no input): `page_break`, `description` Choice fields (`radio`, `checkbox`, `dropdown`) take `choices` as an **array of objects**, not strings — one per option, each `{label, ...}`. Example: ```json {"type": "radio", "label": "How did you hear about us?", "choices": [{"label": "Friend"}, {"label": "Other", "is_other": true}]} ``` `page_break` starts a new page at its position; its `label`/`notes` render as that page's heading. For choice free-text roles (`is_other` / `allow_extended_text`), advanced-field shapes and per-type keys, see `formhug://field-types`; for `api_code` rules, see `formhug://guide`. `header_image` (required): pass 1–2 English search keywords (e.g. "soccer field", "office workspace") and the server picks a suitable image. `layout` (optional): `classic` (default — many questions per scrollable page) or `card` (one question per screen). Only use `card` when the user explicitly asks for a one-question-at-a-time / conversational flow. `scene` (optional): `"quiz"` (exam with correct answers), `"assessment"` (every choice scored), or omit for a regular form. The guide covers per-field scoring keys, score-based feedbacks, and the post-create walkthrough. If this form uses conditional logic (fields that show/hide based on answers, or post-submission redirects), use `get_field_rules` / `update_field_rules` to keep the rules in sync — adding, removing, reordering, or rechoicing rule-referenced fields can invalidate trigger/target api_codes. See `formhug://field-rules`.
create_form
Create a public query page on a form: visitors fill the search fields and see the matching entries' display fields — e.g. students looking up exam scores, applicants checking results, customers checking order status. Read the guide's Public Queries section first for the data-file workflow and how to keep the page from leaking data. Returns the query with its public `url` — share it with the user. Call `get_form` first for the field api_codes. If a field is not allowed, the 422 error lists the allowed api_codes for this form — retry with those. A 402 means the plan lacks public queries or an option you set. Requires the `form:write` scope.
create_public_query
Create a webhook integration on a form. The webhook delivers a JSON payload to `url` whenever any of the subscribed `trigger_events` fires. Use `get_webhook_sample_payload` to preview the payload shape. Requires the `integration:write` scope.
create_webhook
Move one or more entries (up to 200) on a form the user owns or collaborates on to the form's trash, by serial number. Confirm the exact entries with the user before calling. Serial numbers that do not exist or are outside the user's access come back in `failed` with `code: not_found`; the rest are deleted. A 409 means another deletion on this form is still in progress — wait and retry.
delete_entries
Delete a folder. Forms and sub-folders inside it are moved to the desktop (top level).
delete_folder
Permanently delete a form and all its entries. This cannot be undone.
delete_form
Permanently delete a public query; its public page stops working. This cannot be undone. The form and its entries are not affected. Requires the `form:delete` scope.
delete_public_query
Permanently delete a webhook integration. This cannot be undone. Requires the `integration:write` scope.
delete_webhook
Get info about the currently authenticated user: email, display name, avatar, account creation date, total created forms / entries, and billing account details (organization name and current subscription plan code/name/period_end/cancel_at). Useful for confirming who is signed in or checking the current plan.
get_me
Get a single entry by its serial number.
get_entry
Get a form's conditional logic: field display rules (show / abort) and post-submission redirect rules. Read `formhug://field-rules` for the rule shape. Use this before update_field_rules to see what's currently set.
get_field_rules
Get form detail including all field definitions (labels, types, choices). Use this to discover field api_codes before submitting entries or to understand the form structure. `owned` / `role` indicate whether the current user created the form or accesses it as a collaborator (see list_forms).
get_form
Get a form's settings: locale, timezone, after-submission behavior (show_message / redirect / report), availability (manual close, schedule window, entries cap, countdown), access control (password), and submission options (progress bar, field numbering). Use this before update_form_settings to see what's currently set.
get_form_settings
Get the current visual theme of a form: header image(s), wallpaper (color, or a card-layout background image), primary color, submit button style, typography (form_header / field_label / choice_style), general button, and form_container styling. Use this before update_form_theme to see what's currently set. Read formhug://themes for design guidance.
get_form_theme
Get one public query by token, including its public `url`, status, search/display field rules and scope conditions. `status` is `entries_count_limited` when the form has more entries than the plan allows, `form_not_found` when the form was deleted. Requires the `form:read` scope.
get_public_query
Get the public structure of any published form as JSON: its public fields (with api_codes, types, choices) and conditional field-display rules (`field_rules`). Use this to discover field api_codes before calling submit_entry on a form you don't own. `fields` lists every public field, including ones a rule may hide while filling (compute visibility from `field_rules`). Private fields are never returned — however `field_rules` may still reference a private field's api_code as a trigger or target, so a rule can point to an api_code absent from `fields`. Owner-only settings are also excluded — use `get_form` for forms you own. For password-protected forms, pass the password to unlock the structure.
get_published_form
Get an example payload that the webhook would deliver for the given trigger_event. Useful for testing the receiver side. The payload has `event_type` plus a `data` object containing the form token/name and an `entry` keyed by each field's api_code with example values, alongside meta fields (serial_number, created_at, info_*, etc.). Requires the `form:read` scope.
get_webhook_sample_payload
List entries (submissions) on a form the user owns or collaborates on — including when they ask for "my entries" or the responses to their form. Use get_form first to see field api_codes.
list_entries
List all folders owned by the current user (not paginated). Returns `{records}` where each folder includes parent_folder_token (null for top-level), child_folder_count, child_form_count, created_at, and ancestors — a list of {token, name} from the root down to the immediate parent (empty for top-level folders). Use the folder token when creating or moving forms.
list_folders
List forms the current user can access — forms they created plus forms shared with them as a collaborator. Each item carries `owned` (whether the user is the creator) and `role` (the collaboration role on a shared form: manager / data_maintainer / data_viewer / custom; null when owned). Optionally filter by name or folder.
list_forms
List candidate entries for a `linked_form` field on a published form, so you can pick a value and obtain the `entry_token` to submit via submit_entry. Use get_published_form first to find the `linked_form` field's api_code (and its key fields under `associated_fields`). Values are rendered as the published form shows them — the searched key field as plain text, other key/display fields masked where configured. `pagination.total` is an upper bound.
list_linked_form_options
Only for forms the user filled out as a respondent and does NOT own — find them with `list_participated_forms`. To read entries on a form the user created, owns or collaborates on ("my form's entries", "responses to my form"), use `list_entries`: this tool returns 403 on such forms. Lists the entries the user submitted to that published form. Use `get_published_form` first to see field api_codes. Private fields are never included and cannot be filtered or sorted on.
list_my_entries
List forms the current user has submitted entries to but does not own, ordered by most-recent submission. Each item carries the user's own participation stats (`entries_count`, `last_entry_created_at`) plus a form summary. Use `list_my_entries` to read your own submissions on one of these forms.
list_participated_forms
List the public queries the user created. A public query is a public page where visitors look up entries of a form by chosen fields (e.g. an exam-results or order-status lookup). Each item includes its token, form_token, public `url`, status, search/display field rules and scope conditions. Optionally narrow to one form with `form_token`. Requires the `form:read` scope.
list_public_queries
List webhook integrations configured on a form. Returns `{records}`; each webhook entry includes its id, delivery url, subscribed trigger_events (entry_created/entry_updated/entry_paid), enabled flag, and timestamps. Requires the `integration:read` scope on the access token.
list_webhooks
If you have not read `formhug://guide` this session, read it first. Reorder a field within a form by placing it immediately before or after another field. Pass exactly one of `before` or `after` — the anchor field's `api_code`. The moved field's `api_code` cannot be the same as the anchor. For bulk reorders, call this tool once per move. Use `get_form` or `preview_form` to discover api_codes and the current order.
move_field
Move a form into a folder for your own view (folder placement is per-user). Omit folder_token to move the form back to the desktop (root). Provide original_folder_token to authorize a cross-folder move when the form's current folder isn't one you manage. Use get_form to check the form's current folder.token, and list_folders to find available folder tokens. Returns the form's token and its new folder (null on the desktop). Any collaborator on the form may place it in a folder they manage, regardless of their role.
move_form_to_folder
Prepare a 2-step upload for an `attachment` field, returning a one-time `upload_id` and an `upload_url`. This MCP cannot transfer file bytes — YOU (the client) upload the file directly: 1. Call this tool (`dimension_api_code` for a table / matrix column). 2. `PUT` the raw file bytes to the returned `upload_url`, setting `Content-Type` to exactly the declared `content_type`. Use the URL exactly as returned. 3. Submit the `upload_id` under that field in `submit_entry`'s (or `update_entry`'s) `field_values` — always an array of upload_ids, even for a single file: - Plain attachment field: `{ "<field_api_code>": ["<upload_id>"] }` - Table column: `{ "<table_api_code>": [ { "<dimension_api_code>": ["<upload_id>"] } ] }` Call once per file; collect several upload_ids into the array for a multi-file field. The credential expires (see `expires_at`), so PUT and submit promptly.
prepare_entry_attachment_upload
Prepare a 2-step upload for a form-element image (theme, rich-text, or field-element images) or a public query header image, returning a one-time `upload_id` and an `upload_url`. This MCP cannot transfer file bytes — YOU (the client) upload the file directly: 1. Call `prepare_image_upload` with the image's `purpose`, `file_name`, `content_type` (image/jpeg | image/png | image/webp | image/gif), and `file_size` (bytes, ≤ 5 MB). 2. `PUT` the raw file bytes to the returned `upload_url`, setting the `Content-Type` header to exactly the `content_type` you declared. Use the URL exactly as returned — e.g. `curl -X PUT --data-binary @cover.png -H "Content-Type: image/png" "<upload_url>"`. 3. Consume the `upload_id` per `purpose`: - `header_image` → `update_form_theme` `{ "header": { "images": [{ "upload_id": "<upload_id>" }] } }` (or skip uploads entirely by passing `header.image_keywords` — the server auto-picks an Unsplash photo). - `wallpaper_image` → `update_form_theme` `{ "wallpaper": { "image": { "upload_id": "<upload_id>" } } }` (only on `card`-layout forms). - `rich_text_image` → `commit_rich_text_images` to get a public `image_url` for rich-text HTML. - `choice_image` → `choices[].image.upload_id` on an `image_radio` / `image_checkbox` field (create_form / add_fields / update_fields). - `product_image` → `goods_items[].images[].upload_id` on a `product` field. - `booking_image` → `reservation_items[].images[].upload_id` on a `booking` field. - `opensearch_header_image` → `create_public_query` / `update_public_query` `{ "header": { "background_image": { "upload_id": "<upload_id>" } } }`. The credential expires (see `expires_at`), so PUT and apply it promptly.
prepare_image_upload
Get a human-readable markdown preview of a form's structure. Shows the form title, description, shareable URL, and all fields with their types, requirements, and choices. Useful for quickly reviewing a form's layout.
preview_form
Read a FormHug reference document (`formhug://*`) by its URI and return its full text. This is a fallback for clients that cannot read MCP resources directly — if standard MCP resource reading is available, read the `formhug://*` resource that way instead of calling this tool.
read_reference
If you have not read `formhug://guide` this session, read it first. Remove a field from a form by its api_code. Use get_form or preview_form first to find the api_code of the field to remove. Removing a `page_break` merges its page into the previous one.
remove_field
Submit a new entry. Works for both your own forms and any published form. Tries the public endpoint first, then the owner endpoint (unpublished forms you own). Before submitting, discover field api_codes and types: - Your own forms: `get_form` (also exposes field attributes) - Any published form: `get_published_form` `field_values` is a JSON object keyed by each field's api_code. `name` is a single full-name string (e.g. `"Jane Doe"`) — do NOT pass `{first_name, last_name}` or a JSON string of it. The non-obvious shapes: - `phone`: object `{country_id, country_code?, number}` — e.g. `{"country_id": "US", "number": "6267807789"}` - `radio` / `dropdown`: object `{value, other_text?, extended_text?}` where `value` is the choice's api_code (dropdown does not support `extended_text`). A bare string is accepted as shorthand for `{value: <string>}`. Pass `null` to clear. - `checkbox`: array of `{value, other_text?, extended_text?}` (bare strings accepted as shorthand). Empty array clears the selection. - `image_radio` / `image_checkbox`: same as `radio` / `checkbox` but `{value}` only — no `other_text` / `extended_text`. - `rating`: integer 1..rating_max - `nps`: integer 0..10 - `date`: naive wall-clock string formatted per the field's `precision` (`"YYYY-MM"`, `"YYYY-MM-DD"`, `"YYYY-MM-DD HH:mm"`, `"YYYY-MM-DD HH:mm:ss"`); interpreted in the form's `timezone` (defaults to the account's timezone, falling back to UTC) - `address`: `{address_line1, address_line2, city, state, postal_code, country}` - `time`: `{hour, minute, second?}` with integer values, e.g. `{"hour": 14, "minute": 5}` (not strings) - `location`: `{longitude, latitude, address}` - `attachment`: array of `upload_id` strings from `prepare_entry_attachment_upload` (prepare it, then PUT the file to the returned upload_url); omit / empty array when no file. For nested/complex types (`cascade`, `matrix`, `matrix_rating`, `likert`, `ranking`, `table`, `product`, `booking`, `linked_form`) and a full reference, read the resource `formhug://entry-values`. `signature` and `audio` are read-only and cannot be submitted via this MCP — skip them and inform the user. Keys that are not writable fields of the form, and values of the wrong shape, are refused with a 422 listing each offending key. Private fields (`private: true`): on the public-entry endpoint their keys are refused (422) and the server fills each private field's `predefined_value`, if any; only the owner fallback accepts submitted private-field values. Published forms enforce their fill-frequency limits.
submit_entry
Update up to 200 entries on a form the user owns or collaborates on in one call, each with its own `field_values` (only the submitted fields change; same value shapes as `submit_entry`, see `formhug://entry-values`). At most 30 distinct fields may be touched across all rows. Each row is validated on its own: rows outside the user's access or with invalid values come back in `failed` (`code` + `error_details`) and are left untouched, while the rest are saved. Check `failed` and report or retry those rows. Not supported here — use `update_entry` per entry instead: - `attachment` fields, and `table` / `matrix` fields that contain an attachment column (the whole request is rejected). - `booking` and `product` fields (such rows come back in `failed`). - Changes that must notify downstream systems: batch updates trigger no notifications, webhooks or integrations.
update_entries
Update one entry on a form the user owns or collaborates on, identified by its serial number. Only the fields present in `field_values` change; the rest keep their stored values. Keys that are not writable fields are refused (422). Triggers the form's update notifications, webhooks and integrations, like an edit in the FormHug UI. Values take the same shapes as `submit_entry` (see `formhug://entry-values`). `attachment` fields (and attachment columns inside a `table` / `matrix` field): the submitted array REPLACES the stored file list. Read the entry with `get_entry` and include every stored file to keep (by `id`, or as read), plus new `upload_id`s from `prepare_entry_attachment_upload` — e.g. `{"field_3": ["<kept_id>", "<upload_id>"]}`. A file of another entry must be uploaded again. Because `table` / `matrix` values are replaced as a whole too, resubmit every row with its kept file ids when changing any cell. To change many entries at once without attachment, booking or product fields, use `update_entries`.
update_entry
Replace a form's conditional logic. Read `formhug://field-rules` first for the rule shape and trigger/target constraints. Replace semantics: a key you include replaces all rules of that kind; pass [] to clear; omit a key to leave it untouched. Provide the full desired list for any key you send. After updating, tell the user that conditional logic only takes effect on the live form — surface the public form URL (see the guide's URL catalog) and invite them to open it and fill it out to experience the rules in action.
update_field_rules
If you have not read `formhug://guide` this session, read it first. Update one or more existing fields on a form, identified by `api_code`. Call `get_form` first to discover current api_codes, types, and nested shapes (choices, statements, dimensions). A field's `type` is fixed at creation. Merge semantics: keys you supply replace the matching keys on the existing field; keys you omit are preserved. Merging is **shallow** — passing a nested array (`choices`, `statements`, `dimensions`, `sub_choices`, `goods_items`, `reservation_items`) replaces it wholesale, so include every item you want to keep with its existing `api_code`; include a new item with `api_code` omitted (server assigns one); drop an item to delete it. The guide has worked examples. Fields not mentioned in `updates` are left untouched. Use `add_fields` to add, `remove_field` to delete. For Quiz/Assessment forms, if you changed scorable `answers`/`score` values or a choice set, see the guide on following up about score-based feedbacks. If this form uses conditional logic (fields that show/hide based on answers, or post-submission redirects), use `get_field_rules` / `update_field_rules` to keep the rules in sync — adding, removing, reordering, or rechoicing rule-referenced fields can invalidate trigger/target api_codes. See `formhug://field-rules`.
update_fields
Rename a folder. Only the folder name can be changed; folders cannot be moved into other folders via this tool.
update_folder
If you have not read `formhug://guide` this session, read it first. Update a form's name, description, locale, timezone, or layout. To move the form between folders, use move_form_to_folder instead. Theme changes are not done here — use update_form_theme.
update_form
If you have not read `formhug://guide` this session, read it first. Update a form's settings using partial-merge semantics: top-level groups (and individual keys within a group) you omit are left unchanged; explicit `null` clears the corresponding feature. Groups: `locale` / `timezone`, `after_submission` (`mode`: `show_message` / `redirect` / `report`), `availability` (manual close, schedule window, entries cap, countdown), `access_control` (password), `submission_options` (progress bar, field numbering). The `settings` parameter lists each group's keys; the guide shows examples, including the quiz/assessment-only `report` score-based feedbacks.
update_form_settings
If you have not read `formhug://guide` this session, read it first. Update a form's visual theme using partial-merge semantics — keys you include are written, keys you omit are left unchanged, explicit `null` clears a value. Read `formhug://themes` first for design guidance, the full key catalog (fonts, weights, border widths, layout constraints), how to set the header / wallpaper image, palette auto-derivation, and the `primary_color` alias and layout-specific constraints.
update_form_theme
Update a public query. Only the keys you pass change; within `search_button` and `messages` only the sub-keys you pass change. `search_field_rules`, `display_field_rules` and `scope_conditions` are replaced as a whole — read the current query with `get_public_query` first and send the full list. Set `enabled: false` to stop the page from accepting searches. Requires the `form:write` scope.
update_public_query
Update a webhook integration's url, subscribed trigger_events, or enabled flag. Only the fields you pass are changed; omit a field to leave it untouched. Use `list_webhooks` to find the webhook id. Requires the `integration:write` scope.
update_webhook
FormHug ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve FormHug's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are FormHug alternatives on ChatGPT?
As of 2026-11-02, FormHug competes with AllBack, BlockSurvey, CalcForms, Clipform, Cognito MCP, CrowdHum, Dashform, Dayalogs and 33 more in ChatGPT Form & Survey Builders, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.