Flashpoint.AIFlashpoint.AIdocs

Skip logic & conditions

Control survey flow based on respondent answers. Flashpoint.AI uses a single DSL (domain-specific language) for display conditions, skip rules, quota definitions, and variable assignments. Learn the DSL once, use it everywhere.


DSL syntax reference

Conditions are strings evaluated at runtime against the respondent's answers. Question labels (e.g., Q1, Q3) resolve to the respondent's answer for that question.

Operators

OperatorSyntaxDescription
EqualsQ1 == `2` True if Q1's selected option label is 2
Not equalsQ1 != `2` True if Q1's selected option label is not 2
Greater thanQ1 > 18Numeric comparison
Greater or equalQ1 >= 18Numeric comparison
Less thanQ1 < 18Numeric comparison
Less or equalQ1 <= 18Numeric comparison
In listQ1 IN [`1`, `2`, `3`]True if Q1's answer is in the list
Not in listQ1 NOT IN [`4`, `5`]True if Q1's answer is not in the list
And(Q1 == `1`) AND (Q2 > 5)Both conditions must be true
Or(Q1 == `1`) OR (Q2 == `1`)Either condition must be true
NotNOT (Q1 == `1`)Negation
Xor(Q1 == `1`) XOR (Q2 == `1`)Exactly one must be true

Value syntax

  • Option labels are wrapped in backticks: `1`, `2`, `3`
  • Numeric literals are bare: 18, 100, 3.5
  • Strings use quotes: "complete", 'active'
  • Boolean literals: TRUE, FALSE
  • Null: NULL
  • Logical operators are always uppercase: AND, OR, NOT, XOR, IN, NOT IN

Identifiers

An identifier is a question label that resolves to the respondent's answer:

PatternResolves to
Q1Single-select: the selected option. Multi-select: array of selected options
Q3\Row1Grid response: the column selected for Row1. Backslash separates row label
STATUSCurrent response status string (e.g., "COMPLETE")

Multi-select behavior

For multi-select questions, == checks array containment (whether the value is among the selections), not strict equality. IN checks whether any selected option is in the list.

Q5 == `3`              -- true if option 3 is among the selected options
Q5 IN [`1`, `2`, `3`]  -- true if ANY of the selected options is 1, 2, or 3
Q5 NOT IN [`4`, `5`]   -- true if NONE of the selected options is 4 or 5

Aggregate functions

Use with list operands for computed conditions:

FunctionExampleDescription
COUNTCOUNT(Q5) > 2Number of selections in a multi-select
MINMIN(Q5) >= 3Minimum numeric value in a list
MAXMAX(Q5) <= 10Maximum numeric value
MEANMEAN(Q5) > 5Arithmetic mean
MEDIANMEDIAN(Q5) == 5Median value

List functions

FunctionExampleDescription
FILTER_XFILTER_X(Q5, X > 3)Filter list items where the expression is true
MAP_XMAP_X(Q5, X + 1)Transform each list item
OPTIONSOPTIONS(Q3)Access the defined options for a question (for piping)

Arithmetic

The DSL supports arithmetic for computed variables: +, -, *, /, ** (exponent). Standard precedence applies; use parentheses to override.

Q7 + Q8               -- sum of two numeric answers
(Q7 * 100) / Q8       -- percentage calculation
Q9 ** 2               -- square

Display conditions

A display condition on a question controls whether the respondent sees it. If the condition evaluates to false (or the referenced question hasn't been answered yet), the question is skipped silently.

Set the condition field on a question:

{
  "type": "text",
  "text": "What did you dislike about the product?",
  "condition": "Q3 IN [`4`, `5`]"
}

This question only appears if the respondent selected option 4 or 5 on Q3.

API example

curl -X PATCH https://surveys.flashpoint.ai/api/v1/surveys/{survey_id} \
  -H "X-Service-Token: $TOKEN" \
  -H "X-Team-ID: $TEAM_ID" \
  -H "X-User-ID: $USER_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "document": {
      "blocks": [{
        "name": "Follow-up",
        "questions": [{
          "type": "text",
          "text": "What did you dislike about the product?",
          "condition": "Q3 IN [`4`, `5`]"
        }]
      }]
    }
  }'

Agent example

"Add a follow-up question 'What did you dislike about the product?' that only shows if Q3 is 4 or 5"


Skip rules

Skip rules are post-answer branching: after the respondent answers a question, evaluate conditions and route them accordingly. Each question can have multiple skip rules in its skips array.

Skip rule structure

{
  "condition": "Q2 == `1`",
  "action": {
    "type": "skip",
    "label": "Q7"
  }
}

Action types

ActiontypelabelBehavior
Skip to question"skip"Required: target question labelJump to the specified question, skipping everything in between
Disqualify"disqualify"Not usedMark the respondent as disqualified. Survey continues to a terminate screen
Terminate"terminate"Not usedEnd the survey immediately

Examples

Screen out under-18 respondents:

{
  "type": "number",
  "label": "Q1",
  "text": "How old are you?",
  "config": {"datarange": [1, 120]},
  "skips": [
    {
      "condition": "Q1 < 18",
      "action": {"type": "terminate"}
    }
  ]
}

Skip to demographics if they selected "Not interested":

{
  "skips": [
    {
      "condition": "Q5 == `5`",
      "action": {"type": "skip", "label": "Q20"}
    }
  ]
}

Disqualify non-owners:

{
  "skips": [
    {
      "condition": "Q2 == `2`",
      "action": {"type": "disqualify"}
    }
  ]
}

Agent examples

  • "On Q1, if the answer is less than 18, terminate the survey"
  • "On Q3, if they select 'No' (option 2), skip to Q10"
  • "On the screener, if they don't own the product, disqualify them"

Compound conditions

Combine multiple conditions with logical operators. Always wrap sub-expressions in parentheses for clarity.

AND — both must be true

(Q2 == `1`) AND (Q5 IN [`3`, `4`])

Show this question only to males (Q2 option 1) who are in age groups 3 or 4 (Q5).

OR — either can be true

(Q3 == `1`) OR (Q3 == `2`)

Equivalent to Q3 IN [1, 2] but useful when the two conditions reference different questions.

Complex routing

(Q2 == `1`) AND (Q4 >= 25) AND (Q4 <= 34)

Males aged 25-34 only.

((Q1 == `1`) OR (Q1 == `2`)) AND (NOT (Q6 == `5`))

Respondents who chose option 1 or 2 on Q1, but did not choose option 5 on Q6.


Grid conditions

Reference specific rows in a grid question using backslash notation:

Q3\Row1 == `5`

True if the respondent selected column 5 for Row1 in grid question Q3. The part after the backslash is the row's option label.


Variable assignments

Variable questions (type: "variable") store DSL expressions that compute values from other answers. The expression is evaluated at runtime as an assignment program (not a condition).

{
  "type": "variable",
  "label": "V1",
  "text": "Satisfaction score",
  "config": {
    "definition": "Q3 + Q5 + Q7"
  }
}

Variables can reference other variables, creating computed chains. The evaluator handles recursive resolution.

Common variable patterns

PatternExpressionUse case
Sum scoreQ3 + Q5 + Q7Composite index from multiple ratings
Weighted average(Q3 * 2 + Q5 * 3) / 5Weighted satisfaction score
Selection countCOUNT(Q8)How many items they selected in a multi-select
Conditional valueFILTER_X(OPTIONS(Q3), X > 3)Filter selected options above a threshold

Validation tools

Flashpoint.AI provides two validation tools to catch logic errors before publishing.

validate_dsl

Parses a DSL expression and checks syntax. Use before setting complex conditions.

# Agent tool call
validate_dsl(condition="(Q1 == `1`) AND (Q2 > 5)", program_type="condition")

Returns:

{
  "valid": true,
  "identifiers": ["Q1", "Q2"]
}

If invalid:

{
  "valid": false,
  "error": "Unexpected token: \"}\"",
  "identifiers": []
}

Agent prompt: "Validate this condition: (Q1 == 1) AND (Q2 > 5)"

surveycheck

Runs a full validation pass on the entire survey's logic. Call this before publishing to catch:

CheckWhat it catches
Unknown identifiersA skip condition references Q99 but no question has label Q99
Invalid DSLsA condition string that fails to parse
Unreachable questionsA display condition that always evaluates to false
Post-logic identifiersA variable definition references a label that does not exist

The tool also offers corrections — if you reference Q99 but the closest match is Q9, it suggests the fix.

Agent prompt: "Run surveycheck on this survey to validate all the logic before we publish"


Common patterns

Screener with DQ

A typical screener flow: ask a qualifying question, disqualify those who don't qualify, then continue to the main survey.

Q1: "Do you own a car?" (select single: Yes / No)
    skip: Q1 == `2` → disqualify

Q2: "What year is your car?" (year, condition: Q1 == `1`)

S1: "Thank you, you do not qualify." (terminate)

Show-if-selected

Show a follow-up only when a specific option was chosen:

Q3: "Which brands do you use?" (multi-select)
Q4: "What do you like about Nike?" (text, condition: Q3 == `1`)
Q5: "What do you like about Adidas?" (text, condition: Q3 == `2`)

Numeric range gate

Route based on a numeric threshold:

Q7: "How many employees does your company have?" (number)
    skip: Q7 < 50 → skip to Q12     (small business path)
    skip: Q7 >= 500 → skip to Q15   (enterprise path)

Questions Q8-Q11 are the mid-market path (50-499 employees).

Attention check

Insert a question with a known correct answer and terminate respondents who fail:

Q10: "Please select 'Strongly agree' for this question." (select single)
     skip: Q10 != `1` → terminate

Next steps