Get a FoxForm form
foxform_get_formFetch a single form by ID, including its full question list, per-screen conditional logic and settings.
Args:
form_id (string): the form's ID (from foxform_list_forms)
response_format ('markdown' | 'json')
Returns the full form object (id, title, description, slug, status, theme, questions[], thank_you_message, timestamps).
Each screen in questions[] carries its own logic (branching / conditional display) and, for choice screens, choices[]/images[] with their points and value. The markdown output summarises every rule; use response_format 'json' to get the exact stored objects (that's the shape foxform_update_form expects back).
CONDITIONAL LOGIC (branching), per screen — stored in questions[].logic:
logic.conditionalNavigationV2 = { enabled: true, groups: [ // groups are OR-joined; FIRST matching group wins { id: "grp-1", conditions: [ // conditions inside a group are AND-joined { id: "cond-1", left: "{{quer_testar}}", operator: "equal_to", right: "Ainda não" } ], then: { type: "specific_screen", targetScreenId: "s-motivos" } } ] }
then.type: 'next_screen' | 'previous_screen' | 'specific_screen' (needs targetScreenId = another screen'sid) | 'end_form'. Addthen.url(+ optionalopenNewTab) to redirect to an external URL instead.operator: 'equal_to' | 'not_equal_to' | 'greater_than' | 'greater_or_equal_than' | 'less_than' | 'less_or_equal_than' | 'contains'.left/rightare EXPRESSION strings: a literal ("10", "Ainda não"), a variable ("{{score}}", "{{minha_var}}" = the screen'svariableName), or arithmetic ("calc({{peso}}/(({{altura}}/100)*({{altura}}/100)))").Comparing an ANSWER: use
left: "{{<variableName of the deciding screen>}}"andright= the option'slabelOR itsvalue(both match).{{score}}is the running sum ofpointson the options picked so far (choices[].points,images[].points) — that is how score-based branching works.A navigation group with no conditions NEVER matches.
enabled: falsestores the rules but disables them.Screen-level conditional display uses the same group shape:
logic.display = { enabled: true, groups: [...], showAfterSeconds?: n }(thenis ignored — THEN means "show").Other logic keys:
logic.autoAdvance = { enabled, delaySeconds? },logic.navigationBehavior = { onButtonClick?, onAutoAdvance?, targetScreenId? }.logic.conditionalNavigation(legacy, pre-DEVF-161) is still read and migrated on load — don't author new rules with it.
Unknown fields are REJECTED (they used to be stored and silently ignored): logic as an array, or rules/branching/conditions/goto/jump/nextScreen anywhere, are not read by any renderer.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| form_id | Yes | Form ID | |
| response_format | No | Output format: 'markdown' (human-readable) or 'json' (machine-readable) | markdown |