---
title: "Get one version, with its config"
method: GET
path: "/external/v1/flows/{flow_id}/versions/{number}"
tags: ["Flows"]
---

# Get one version, with its config

`GET /external/v1/flows/{flow_id}/versions/{number}`

## Request

- Base URL: `https://api.databar.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.databar.ai/external/v1/flows/{flow_id}/versions/{number}`
- Auth: API key in header `x-apikey`

## Path parameters

- `flow_id` string, required
- `number` integer, required

## Response `200`

OK

- FlowVersionDetailOut
  - `number` integer, required
  - `name` string, required
  - `description` string, required
  - `changed_fields` string[], required
  - `source` string, required: Where the edit came from: ui, api, mcp, admin or system.
  - `created_at` string, required
  - `created_by` string, nullable, required
  - `restored_from` integer, nullable: Version this one was restored from, if it came from a rollback.
  - `config` FlowDefinition, required
    - `inputs` FlowDefFunctionInput[]
      - `id` string, required
      - `description` string
      - `type` string: Same vocabulary as RequestParam.type_data.
      - `required` boolean: If true, input_bindings must include this id when attaching the function to a table.
    - `nodes` union[], required
      - union
        - FlowDefEnrichmentNode
          - `id` string, required
          - `type` 'enrichment'
          - `label` string
          - `on_error` 'stop' | 'skip': What to do when the enrichment call fails: stop the whole run or skip this node.
          - `on_no_data` 'stop' | 'skip': What to do when the enrichment returns no data: stop the run or skip this node.
          - `data` FlowDefEnrichmentNodeData, required
            - `enrichment_id` integer, required
            - `authorization_id` integer, nullable: UserKey PK to use for this enrichment call. Omit to use the workspace default key.
            - `inputs` union[]: Input slot bindings: each item maps a param slug (id) to a source — function input, node output, or static value.
              - …
            - `outputs` FlowDefOutputPort[]: Node outputs (id + optional response_field_id); values from ResponseField or full response.
              - …
        - FlowDefConditionNode
          - `id` string, required
          - `type` 'condition'
          - `label` string
          - `on_error` 'stop' | 'skip': What to do when formula evaluation raises an exception.
          - `data` FlowDefConditionNodeData, required
            - `inputs` union[]: Values to expose as {{id}} variables inside the CEL formula.
              - …
            - `formula` string, required: CEL expression using {{input_id}} references. E.g. '{{email}} != ""'.
            - `then_nodes` string[]: Node ids to SKIP when formula evaluates to FALSE.
            - `else_nodes` string[]: Node ids to SKIP when formula evaluates to TRUE.
        - FlowDefJqNode: Transform a JSON value using a jq expression.
          - `id` string, required
          - `type` 'jq'
          - `label` string
          - `on_error` 'stop' | 'skip': What to do when the jq program raises: stop the run or skip this node.
          - `data` FlowDefJqNodeData, required: Data for a JQ transform node — runs a jq expression on one or more JSON inputs.
            - `inputs` union[]: Input slot bindings. Shape of the value passed to jq is controlled by ``input_shape``: ``value`` (legacy) passes a single input as-is; ``object`` always wraps bindings into ``{id: value, ...}``.
              - …
            - `expression` string, required: jq program. With one input and input_shape ``value`` (the default), ``.`` is that input's value itself, so a text input is a plain string (e.g. '. | split(" ")'); with ``object`` or several inputs, ``.`` is ``{slot_id: value, ...}`` (e.g. '.name' or '.items[] | select(.active)').
            - `outputs` FlowDefOutputPort[]: Exactly one output port, carrying the whole jq result. Downstream refs reach into it by path (`<port>.field.sub`).
              - …
            - `input_shape` 'value' | 'object': How inputs are assembled for jq. ``value``: single input passed as-is (legacy). ``object``: always ``{slot_id: value, ...}``.
        - FlowDefMergeNode: Concatenate multiple string inputs into a single value.
          - `id` string, required
          - `type` 'merge'
          - `label` string
          - `on_error` 'stop' | 'skip'
          - `data` FlowDefMergeNodeData, required: Data for a merge/concatenate node.
            - `inputs` union[]: Input slot bindings to concatenate in order; empty/null values are skipped.
              - …
            - `separator` string: String inserted between non-empty parts, e.g. ' ' or ', '.
            - `outputs` FlowDefOutputPort[]: Exactly one output port, carrying the merged string.
              - …
        - FlowDefMathFunctionNode: Evaluate an arithmetic expression with SymPy (Math Function tool).
          - `id` string, required
          - `type` 'math_function'
          - `label` string
          - `on_error` 'stop' | 'skip'
          - `data` FlowDefMathFunctionNodeData, required: Data for a Math Function node — evaluates a SymPy arithmetic expression.
            - `inputs` union[]: Input slot bindings; each binding's 'id' must match a symbol name in the expression. E.g. id='price', value=upstream node output → used as 'price' in the formula.
              - …
            - `expression` string, required: SymPy-compatible arithmetic expression, e.g. 'price * 0.9' or 'a + b / 2'.
            - `outputs` FlowDefOutputPort[]: Exactly one output port, carrying the numeric result as a string.
              - …
        - FlowDefTableLookupNode: Query another Databar table and return matching rows as JSON.
          - `id` string, required
          - `type` 'table_lookup'
          - `label` string
          - `on_error` 'stop' | 'skip'
          - `data` FlowDefTableLookupNodeData, required: Data for a table-lookup node — queries another Databar table.
            - `lookup_table` string, required: UUID (identifier) of the target table to query.
            - `lookup_column` string, required: UUID (identifier) of the column in the lookup table to filter on.
            - `operator` string: Filter operator: 'equals' (exact match) or 'contains' (case-insensitive substring).
            - `inputs` union[]: The search value binding. The first input's resolved value is used as the lookup value.
              - …
            - `outputs` FlowDefOutputPort[]: Exactly one output port, carrying the JSON list of matching rows. Downstream refs reach into it by path (`<port>.0.column`).
              - …
        - FlowDefWaterfallNode: Run a multi-provider waterfall enrichment pipeline.
          - `id` string, required
          - `type` 'waterfall'
          - `label` string
          - `on_error` 'stop' | 'skip': What to do when the waterfall fails: stop the run or skip this node.
          - `on_no_data` 'stop' | 'skip': What to do when no provider returns data: stop the run or skip this node.
          - `data` FlowDefWaterfallNodeData, required: Data for a waterfall node — runs ordered enrichments until one succeeds.
            - `waterfall_identifier` string, required: Stable slug of the waterfall script, e.g. 'email_getter'.
            - `enrichments` integer[]: Ordered enrichment ids to try. Empty list uses the script's default cascade, omitting providers hidden by default.
            - `email_verifier_id` integer, nullable: Optional email-verifier enrichment id for verifying waterfalls.
            - `per_enrichment_authorization` object, nullable: Map of enrichment_id → UserKey PK for per-provider API keys.
            - `inputs` union[]: Input slot bindings; each id is a waterfall Param name.
              - …
            - `outputs` FlowDefOutputPort[]: Output ports; each id is a waterfall Result name. response_field_id is unused for waterfall nodes.
              - …
    - `named_outputs` FlowDefNamedFlowOutput[], nullable
      - `id` string, required
      - `key` string, required
      - `name` string, required
      - `source` FlowDefFlowOutputSource
        - `node_id` string, required
        - `ref` string, nullable
      - `mapping` FlowDefFlowOutput: Flow-level output mapping: reshape the run result into a custom shape. Two mutually-exclusive modes: * :attr:`fields` — structured mapping. Each entry is a :data:`NodeInput` whose ``id`` becomes the key in the returned ``outputs`` object. * :attr:`template` — a raw JSON string the user writes directly, with ``{{ input.x }}`` / ``{{ nodes.id.port }}`` tokens resolved at runtime. Supports arbitrary nested JSON, not just a flat object. When ``FlowDefinition.output`` is set, the executor returns the reshaped result instead of the raw namespaced ``{node_id: {port: value}}`` dict.
        - `fields` union[]: Output field bindings; each `id` is the key in the returned outputs object.
          - union
            - FlowDefInputRef: Binds a node input slot to a function-level input.
              - …
            - FlowDefNodeRef: Binds a node input slot to an output of another node.
              - …
            - FlowDefStaticRef: Binds a node input slot to a hardcoded value.
              - …
            - FlowDefStaticWithRefsInput: Binds a node input slot to a template string with ``{ref_id}`` substitutions. Used for prompt-text style fields where the resolved value is a literal with references interpolated inline, e.g. ``"Tell me about {company}"`` where ``company`` is a nested ref to a function input or upstream node output. Tokens supported: * ``{name}`` — required ref; raises ``ValueError`` if no matching entry in :attr:`refs` resolves to a value (i.e. the ref is missing or the upstream port is unset). An unmatched name that equals a function input id is treated as that input (MCP/UI often persist ``{domain}`` with empty refs). * ``{?name}`` — optional ref; falls back to ``""`` when missing. The token character set matches the table-side rich editor (``[a-zA-Z0-9_.]``) so prompts copied from a table workflow keep working.
              - …
        - `template` string, nullable: Raw JSON template with `{{ input.x }}` / `{{ nodes.id.port }}` tokens. Overrides `fields`.
      - `combine` string[]
      - `combine_fields` FlowDefCombinedOutputField[]
        - `id` string, required
        - `output_id` string, required
        - `path` string
    - `output` FlowDefFlowOutput: Flow-level output mapping: reshape the run result into a custom shape. Two mutually-exclusive modes: * :attr:`fields` — structured mapping. Each entry is a :data:`NodeInput` whose ``id`` becomes the key in the returned ``outputs`` object. * :attr:`template` — a raw JSON string the user writes directly, with ``{{ input.x }}`` / ``{{ nodes.id.port }}`` tokens resolved at runtime. Supports arbitrary nested JSON, not just a flat object. When ``FlowDefinition.output`` is set, the executor returns the reshaped result instead of the raw namespaced ``{node_id: {port: value}}`` dict.
      - `fields` union[]: Output field bindings; each `id` is the key in the returned outputs object.
        - union
          - FlowDefInputRef: Binds a node input slot to a function-level input.
            - `id` string, required: Slot id (param slug on the enrichment dataset).
            - `from` 'function', required
            - `ref` string, required: Id of the FunctionInput being referenced.
          - FlowDefNodeRef: Binds a node input slot to an output of another node.
            - `id` string, required: Slot id (param slug on the enrichment dataset).
            - `from` 'node', required
            - `node_id` string, required
            - `ref` string, required: OutputPort.id on the referenced node.
          - FlowDefStaticRef: Binds a node input slot to a hardcoded value.
            - `id` string, required: Slot id (param slug on the enrichment dataset).
            - `from` 'static', required
            - `value` string, required: Hardcoded string value passed directly to the enrichment param.
          - FlowDefStaticWithRefsInput: Binds a node input slot to a template string with ``{ref_id}`` substitutions. Used for prompt-text style fields where the resolved value is a literal with references interpolated inline, e.g. ``"Tell me about {company}"`` where ``company`` is a nested ref to a function input or upstream node output. Tokens supported: * ``{name}`` — required ref; raises ``ValueError`` if no matching entry in :attr:`refs` resolves to a value (i.e. the ref is missing or the upstream port is unset). An unmatched name that equals a function input id is treated as that input (MCP/UI often persist ``{domain}`` with empty refs). * ``{?name}`` — optional ref; falls back to ``""`` when missing. The token character set matches the table-side rich editor (``[a-zA-Z0-9_.]``) so prompts copied from a table workflow keep working.
            - `id` string, required: Slot id (param slug on the enrichment dataset).
            - `from` 'static_with_refs', required
            - `template` string, required: Template string with `{ref_id}` (required) or `{?ref_id}` (optional) placeholders.
            - `refs` union[]: Refs to substitute into the template. Each `ref.id` matches a `{ref.id}` placeholder.
              - …
      - `template` string, nullable: Raw JSON template with `{{ input.x }}` / `{{ nodes.id.port }}` tokens. Overrides `fields`.
  - `ui` object, required

---

[API](https://skmtc.dev/databar/apis/external-api.md) - [All operations](https://skmtc.dev/databar/apis/external-api/llms.txt) - [OpenAPI document](https://skmtc.dev/databar/apis/external-api/revisions/efe15f8bb9bb?raw)
