# Integrations

Define external API connections. Integrations use the dual naming scheme (ID + label):

```
integrations:    
      # ID is the map key (immutable), label is display name (can change)    
      banking_api: # ID - immutable reference    
        label: 'Banking API' # Display name - can change freely    
        type: rest    
        base_url: https://api.bank.com/v2    
        auth:    
          type: bearer    
          access_token: 'your-bearer-token' # Required for bearer    
          test_url: 'https://api.bank.com/v2/health' # Optional: URL to verify the connection    
         
        methods:    
          get_account_balance: # Method ID - immutable    
            description: 'Get account balance' # Optional method description    
            http: GET /accounts/{accountId}/balance    
            query: 'accountType={accountType}' # Query string template    
            response:    
              type: single    
              result_path: '$.data' # Path to result object within response envelope    
              record_path: '$.balance' # Path to records within the result    
              limit: 10    
              record_template: '{amount}' # Record display template    
              valid_template: 'Balance: {amount}' # Message when results found    
              empty_template: 'No balance found' # Message when no results    
         
          validate_pin:    
            description: 'Validate PIN'    
            http: POST /auth/validate    
            body: '{"accountId":"{{accountId}}","pin":"{{pin}}"}'    
            response:    
              type: entry # Raw JSON to agent    
         
          get_transactions:    
            description: 'Get Recent Transactions'    
            http: GET /accounts/{accountId}/transactions    
            query: 'limit=10'    
            response:    
              type: list    
              record_path: '$.transactions[*]'    
              limit: 10    
         
      # Simple integration - no auth    
      swapi:    
        type: rest    
        base_url: https://swapi.dev    
        auth:    
          type: none    
         
        methods:    
          search_people:    
            http: GET /api/people/    
            query: 'search={search}'    
            response:    
              type: list    
              record_path: '$.results[*]'    
              limit: 20    
```

#### **Response Block Fields**

A Response Block defines what the system sends back to the user at a given point in the flow.

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">Field</td><td valign="top">Type</td><td valign="top">Maps to VNext</td><td valign="top">Description</td></tr><tr><td valign="top">type:</td><td valign="top">string</td><td valign="top">output.resultType</td><td valign="top">entry, single, list, Entry, List</td></tr><tr><td valign="top">result_path:</td><td valign="top">string</td><td valign="top">output.resultPath</td><td valign="top">JSONPath to result object within response</td></tr><tr><td valign="top">record_path:</td><td valign="top">string</td><td valign="top">output.recordPath</td><td valign="top">JSONPath to records within the result</td></tr><tr><td valign="top">limit:</td><td valign="top">number</td><td valign="top">output.recordLimit</td><td valign="top">Maximum records to return</td></tr><tr><td valign="top">record_template:</td><td valign="top">string</td><td valign="top">output.recordTemplate</td><td valign="top">Record display template</td></tr><tr><td valign="top">valid_template:</td><td valign="top">string</td><td valign="top">result.validResultTemplate</td><td valign="top">Message when results are found</td></tr><tr><td valign="top">empty_template:</td><td valign="top">string</td><td valign="top">result.emptyResultTemplate</td><td valign="top">Message when no results found</td></tr></tbody></table>

### **Connection-level fields**

A connection represents a long‑lived interaction context between a user and the system.

Connection‑level fields apply to the entire conversation session, not just a single response or node.

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">Field</td><td valign="top">Type</td><td valign="top">Maps to Customer v2</td><td valign="top">Description</td></tr><tr><td valign="top">type:</td><td valign="top">string</td><td valign="top">integrationType</td><td valign="top">rest or mcp</td></tr><tr><td valign="top">base_url:</td><td valign="top">string</td><td valign="top">configuration.settings.baseUrl</td><td valign="top">REST base URL</td></tr><tr><td valign="top">endpoint:</td><td valign="top">string</td><td valign="top">configuration.settings.endpointUrl</td><td valign="top">MCP SSE endpoint URL</td></tr><tr><td valign="top">auth.type:</td><td valign="top">string</td><td valign="top">configuration.settings.authType</td><td valign="top">none, basic, bearer, apikey, oauth2, customheaders</td></tr><tr><td valign="top">auth.access_token:</td><td valign="top">string</td><td valign="top">configuration.settings.token</td><td valign="top">Bearer token value</td></tr><tr><td valign="top">auth.test_url:</td><td valign="top">string</td><td valign="top">configuration.settings.testResourceUrl</td><td valign="top">URL to validate the connection (bearer)</td></tr><tr><td valign="top">auth.username:</td><td valign="top">string</td><td valign="top">configuration.settings.username</td><td valign="top">Username (basic auth)</td></tr><tr><td valign="top">auth.password:</td><td valign="top">string</td><td valign="top">configuration.settings.password</td><td valign="top">Password (basic auth)</td></tr><tr><td valign="top">auth.auth_url:</td><td valign="top">string</td><td valign="top">configuration.settings.authUrl</td><td valign="top">Authorization URL (basic auth / oauth2 authorization_code only)</td></tr><tr><td valign="top">auth.grant_type:</td><td valign="top">string</td><td valign="top">configuration.settings.grantType</td><td valign="top">OAuth2 grant type: authorization_code or client_credentials</td></tr><tr><td valign="top">auth.token_url:</td><td valign="top">string</td><td valign="top">configuration.settings.tokenUrl</td><td valign="top">OAuth2 token endpoint URL</td></tr><tr><td valign="top">auth.client_id:</td><td valign="top">string</td><td valign="top">configuration.settings.clientId</td><td valign="top">OAuth2 client ID</td></tr><tr><td valign="top">auth.client_secret:</td><td valign="top">string</td><td valign="top">configuration.settings.clientSecret</td><td valign="top">OAuth2 client secret</td></tr><tr><td valign="top">auth.scope:</td><td valign="top">string</td><td valign="top">configuration.settings.scope</td><td valign="top">OAuth2 scope (space-separated)</td></tr><tr><td valign="top">auth.custom_headers:</td><td valign="top">string</td><td valign="top">configuration.settings.customHeaders</td><td valign="top">Custom headers JSON string (any type)</td></tr><tr><td valign="top">description:</td><td valign="top">string</td><td valign="top">description</td><td valign="top">Human-readable description</td></tr><tr><td valign="top">shared:</td><td valign="top">bool</td><td valign="top">isShared</td><td valign="top">Shared across flows</td></tr><tr><td valign="top">connectionId:</td><td valign="top">string</td><td valign="top">id</td><td valign="top">VNext UUID (omitted with stripUuids)</td></tr><tr><td valign="top">methods:</td><td valign="top">block</td><td valign="top">methodDefinitions</td><td valign="top">REST only — not present for type: mcp (tools auto-discovered)</td></tr></tbody></table>

`result_path` vs `record_path`: result\_path navigates to the result object within the response envelope (e.g. $.data). record\_path navigates to individual records within that result (e.g. $.items\[\*]). Both are optional JSONPath expressions.

### **Auth Block**

An Auth Block is a dedicated, declarative unit that handles user authentication and authorization within a conversation.

*auth*: is a structured block with *type*: plus type-specific credential fields.

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">`type:` value</td><td valign="top">VNext value</td><td valign="top">Credential fields under `auth:`</td></tr><tr><td valign="top">none</td><td valign="top">NoAuth</td><td valign="top"><em>(none)</em></td></tr><tr><td valign="top">basic</td><td valign="top">Basic</td><td valign="top">username:, password:, auth_url: (optional)</td></tr><tr><td valign="top">bearer</td><td valign="top">Bearer</td><td valign="top">access_token:, test_url: (optional)</td></tr><tr><td valign="top">apikey</td><td valign="top">ApiKey</td><td valign="top"><em>(TBD)</em></td></tr><tr><td valign="top">oauth2</td><td valign="top">OAuth2</td><td valign="top">grant_type: (authorization_code|client_credentials), token_url:, client_id:, client_secret:, scope:, auth_url: (authorization_code only)</td></tr><tr><td valign="top">customheaders</td><td valign="top">CustomHeaders</td><td valign="top">custom_headers: JSON string (available for any integration type)</td></tr></tbody></table>

#### No Auth:

No Auth means no authentication or authorization is required to proceed. The flow is public, open, and does not verify identity.

Anyone can continue without login, OTP, SSO, or credentials.        &#x20;

```
    auth:    
      type: none    
```

#### Basic Auth:

Basic Auth is a simple authentication mechanism where the system verifies a user using a username + password (or client ID + secret) before allowing access to a protected flow or integration.

```
auth:    
      type: basic    
      username: user@example.com    
      password: 'your-password'    
      auth_url: https://api.example.com/auth # optional    
```

#### Bearer Token:

A Bearer Token is a secure access token that grants permission to access a protected resource without resending credentials each time.      &#x20;

```
    auth:    
      type: bearer    
      access_token: 'your-bearer-token'    
      test_url: https://api.example.com/health # optional    
```

#### OAuth2 — Authorization Code (has auth\_url):

The Authorization Code flow is the most secure OAuth 2.0 flow for user‑based authentication.

It is used when:

* A real user must log in
* The system must redirect the user to an identity provider
* Tokens are exchanged server‑to‑server, not exposed to the user

```
    auth:    
      type: oauth2    
      grant_type: authorization_code    
      token_url: https://api.example.com/oauth/token    
      client_id: your-client-id    
      client_secret: 'your-client-secret'    
      scope: 'read write'    
      auth_url: https://api.example.com/oauth/authorize    
```

#### OAuth2 — Client Credentials (no auth\_url):

The Client Credentials flow is an OAuth 2.0 flow where no human user is involved.

Instead:

* A system (client) authenticates itself
* Using a client\_id + client\_secret
* It receives a Bearer access token
* That token is used to call protected APIs

```
    auth:    
      type: oauth2    
      grant_type: client_credentials    
      token_url: https://api.example.com/oauth/token    
      client_id: your-client-id    
      client_secret: 'your-client-secret'    
      scope: 'read write'             
```

#### MCP Custom Headers:

MCP Custom Headers are additional HTTP headers attached to MCP requests when your system communicates with an MCP server (tools, data sources, services).

They are used to:

* Pass authentication tokens
* Forward tenant or org context
* Enable tracing and observability
* Apply feature flags or routing hints
* Meet enterprise security requirements

```
    auth:    
      type: customheaders    
      custom_headers: '{"x-api-key":"your-key"}'    
```

#### Referencing Integrations

Referencing an integration means:

* You define an integration once (API, MCP tool, service call)
* Then invoke it by name or reference inside flows, responses, or routing logic

Nodes reference integrations and methods by their ID (not label):

```
nodes:    
      - check_balance:    
          type: api    
          integration: banking_api # References integration ID    
          method: get_account_balance # References method ID    
          params:    
            accountId: '{account_number}'    
          exits:    
            success:    
              next: show_balance    
            failure:    
              next: api_error    
```

#### Renaming Behavior

Renaming behavior describes what happens when you:

* Reference an integration, node, or block under a different name
* Alias outputs to a new logical name
* Override default identifiers for clarity, reuse, or conflict avoidance

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">Action</td><td valign="top">What Changes</td><td valign="top">References</td></tr><tr><td valign="top">Change label</td><td valign="top">Display name only</td><td valign="top">Unchanged - all references still work</td></tr><tr><td valign="top">Change ID</td><td valign="top">Not allowed</td><td valign="top">Would break references (like renaming a variable)</td></tr></tbody></table>

### MCP Integrations

For Model Context Protocol servers. MCP integrations do not define methods - tools are\
discovered dynamically at runtime.

#### Remote MCP Server (SSE transport):

A Remote MCP Server is an MCP‑compliant service that:

* Lives outside your conversational platform
* Exposes tools, resources, or prompts
* Is accessed over the network (HTTP)
* Communicates using a supported transport

When using **SSE transport**, the client:

* Opens a **long‑lived HTTP connection**
* Receives **server‑initiated messages** as events
* Does **not** poll repeatedly

```
integrations:    
      retail_mcp: # ID - immutable    
        label: 'Retail MCP Server' # Display name    
        type: mcp    
        endpoint: https://api.example.com/mcp/sse    
        auth:    
          type: customheaders    
          custom_headers: '{"x-api-key":"your-api-key-here"}'    
```

#### Local MCP Server (stdio transport):

A Local MCP Server is an MCP‑compliant server that:

* Runs locally on the same machine as the MCP client
* Is typically launched as a child process
* Communicates over standard input/output (`stdio`)
* Does not expose a network endpoint

**Key Points:**

* MCP integrations use type: mcp (not rest)
* Remote servers use endpoint: with SSE URL
* Local servers use command: and args:
* Methods are not declared - MCP discovers tools dynamically
* Authentication via auth: custom\_headers with custom\_headers: JSON string
* ID + label scheme applies to MCP integrations too

### Complete Example

A banking assistant using all core node types (v1.5 syntax with branch, set, and unified exits:\
pattern):

```
yflow: '1.4'    
         
    flow:    
      name: Banking Assistant    
      persona:    
        language: en-US    
        voice: Jessica    
      version: '1.0.0'    
         
    nodes:    
      - start:    
          next: welcome_message    
         
      - welcome_message:    
          type: say    
          message: |    
            Welcome to First National Bank.    
            How can I help you today?    
          next: auth_agent    
         
      # Collect account number and PIN    
      - auth_agent:    
          type: agent    
          take_initiative: true    
          iteration_limit: 2    
          system: |    
            Ask the user for their account number and 4-digit PIN.    
            When you have both, trigger 'authenticate'.    
          goals:    
            authenticate:    
              description: User provided account and PIN    
              slots:    
                account_number:    
                  type: string    
                  description: 'Account number'    
                pin:    
                  type: string    
                  description: '4-digit PIN'    
              next: validate_pin_api    
          fallback:    
            next: auth_error    
         
      # Validate PIN via API    
      - validate_pin_api:    
          type: api    
          integration: banking_api    
          method: validate_pin    
          params:    
            accountId: '{account_number}'    
            pin: '{pin}'    
          result_prefix: auth    
          exits:    
            success:    
              next: main_agent    
            failure:    
              next: auth_error    
         
      - auth_error:    
          type: say    
          message: I wasn't able to verify your identity.    
          next: end_1    
         
      # Main conversational agent    
      - main_agent:    
          type: agent    
          iteration_limit: 10    
          system: |    
            You are a helpful banking assistant for {auth_user_name}.    
         
            When the user wants to check their balance, trigger 'check_balance'.    
            When the user wants to speak to someone, trigger 'transfer'.    
            When the user is done, trigger 'goodbye'.    
          goals:    
            check_balance:    
              description: User wants to check account balance    
              slots:    
                account_type:    
                  type: string    
                  description: 'checking or savings'    
              next: get_balance_api    
         
            transfer:    
              description: User wants to speak to a person    
              next: transfer_to_agent    
         
            goodbye:    
              description: User is done    
              next: farewell    
         
          fallback:    
            next: agent_error    
         
      - agent_error:    
          type: say    
          message: Something went wrong. Let me try again.    
          next: farewell    
         
      # Check balance via API (unified exits pattern)    
      - get_balance_api:    
          type: api    
          integration: banking_api    
          method: get_balance    
          params:    
            accountId: '{account_number}'    
            type: '{account_type}'    
          result_prefix: balance    
          exits:    
            success:    
              next: format_balance    
            failure:    
              next: api_error    
         
      - api_error:    
          type: say    
          message: I couldn't reach our systems right now. Let me try again.    
          next: main_agent    
         
      # Set node: compute display values from API result    
      - format_balance:    
          type: set    
          assignments:    
            - target: display_balance    
              expression: "$format(balance_json.amount, 'currency')"    
            - target: balance_amount    
              expression: 'balance_json.amount'    
              type: number    
          error: api_error    
          next: check_balance_level    
         
      # Branch node: route based on balance level    
      - check_balance_level:    
          type: branch    
          conditions:    
            - label: high_balance    
              expression: 'balance_amount > 10000'    
              next: premium_message    
            - label: low_balance    
              expression: 'balance_amount < 100'    
              next: low_balance_warning    
          else:    
            target: speak_balance    
         
      - premium_message:    
          type: say    
          message:    
            'Great news! Your {account_type} balance is {display_balance}. As a premium client, ask    
            about our investment options.'    
          next: main_agent    
         
      - low_balance_warning:    
          type: say    
          message:    
            'Your {account_type} balance is {display_balance}. Would you like to set up a transfer or    
            deposit?'    
          next: main_agent    
         
      - speak_balance:    
          type: say    
          message: 'Your {account_type} balance is {display_balance}.'    
          next: main_agent    
         
      # Transfer to human agent (unified exits pattern)    
      - transfer_to_agent:    
          type: transfer    
          destination: tel:+18005551234    
          label: Customer Service    
          exits:    
            error:    
              next: transfer_failed    
         
      - transfer_failed:    
          type: say    
          message: I couldn't complete the transfer. Let me try something else.    
          next: main_agent    
         
      - farewell:    
          type: say    
          message: Thank you for banking with us. Goodbye!    
          next: end_1    
         
      - end_1:    
          type: end    
         
    # ============================================================================    
    # INTEGRATIONS    
    # ============================================================================    
    integrations:    
      banking_api: # ID - immutable    
        label: 'Banking API' # Display name - can change    
        type: rest    
        base_url: https://api.bank.com/v2    
        auth:    
          type: bearer    
         
        methods:    
          validate_pin: # Method ID    
            description: 'Validate PIN'    
            http: POST /auth/validate    
            body:    
              accountId: '{accountId}'    
              pin: '{pin}'    
            response:    
              type: entry    
         
          get_balance:    
            description: 'Get Balance'    
            http: GET /accounts/{accountId}/balance    
            query: 'type={type}'    
            response:    
              type: single    
              record_path: '$.balance'    

```

**This example demonstrates:**

* All core node types: start, end, say, agent, api, transfer, set, branch
* Set node: Compute display values from API results using ExpressionEngine ($format,\
  arithmetic)
* Branch node: Route based on balance level with per-condition exits and else default
* Unified \`exits:\` pattern (v1.4): API and Transfer nodes use exits: with next: inside each\
  named exit
* Dual naming scheme: integration IDs for references, labels for display
* Variable syntax: {variable} for references, bare values for constants
* Agent behavioral flags: take\_initiative, iteration\_limit, fallback
* API result prefixing: result\_prefix: balance → variables like {balance\_json}

### Schema & Validation

YFlow can be validated with JSON Schema:

```
# yflow.schema.yaml    
    $schema: http://json-schema.org/draft-07/schema#    
    title: YFlow Schema    
    type: object    
         
    properties:    
      yflow:    
        type: string    
        pattern: "^[0-9]+\\.[0-9]+$"    
         
      flow:    
        type: object    
        required: [name, version]    
        properties:    
          name: { type: string }    
          version:    
            type: string    
            pattern: "^[0-9]+\\.[0-9]+\\.[0-9]+(-[a-zA-Z0-9.]+)?(\\+[a-zA-Z0-9.]+)?$"    
            description: 'SemVer version (MAJOR.MINOR.PATCH)'    
          persona:    
            type: object    
            properties:    
              language: { type: string }    
              voice: { type: string }    
              llmModel: { type: string }    
         
      # Nodes as ordered array of single-key maps    
      nodes:    
        type: array    
        items:    
          type: object    
          minProperties: 1    
          maxProperties: 1    
          additionalProperties:    
            $ref: '#/definitions/node'    
         
    definitions:    
      node:    
        oneOf:    
          - $ref: '#/definitions/start_node'    
          - $ref: '#/definitions/end_node'    
          - $ref: '#/definitions/say_node'    
          - $ref: '#/definitions/agent_node'    
          - $ref: '#/definitions/menu_node'    
          - $ref: '#/definitions/api_node'    
          - $ref: '#/definitions/transfer_node'    
          - $ref: '#/definitions/tools_node'    
          - $ref: '#/definitions/branch_node'    
          - $ref: '#/definitions/set_node'    
         
      # ... node type definitions    
```

### Tooling Ideas

* yflow validate - Validate syntax and schema
* yflow visualize - Generate flow diagram
* yflow convert - Convert to/from VNext JSON
* yflow simulate - Interactive flow testing
* yflow lint - Style and best practice checks


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ixhello.com/ixhc2/technical-specifications/yflow-a-yaml-based-conversational-flow-language/integrations.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
