> ## Documentation Index
> Fetch the complete documentation index at: https://docs.liberate.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Task node

# Task Node

The **Task Node** connects your workflow to external systems via HTTP. Use it to create claims in Snapsheet, look up policies in Guidewire, update records in Salesforce, or call any REST API.

> [!NOTE]
>
> Task Nodes are how workflows interact with the outside world. Every integration—whether to your AMS, claims system, or CRM—uses a Task Node.

## Overview

Use a Task Node when you need to:

* Create records in external systems (claims, policies, activities)
* Look up data from your AMS or core systems
* Update customer information in your CRM
* Send notifications via external services
* Call any REST API endpoint

***

## Prerequisites: Connections

Before using a Task Node, you must create a **Connection** to your target system. Connections store authentication credentials and base URLs for each environment.

### Creating a Connection

1. Click **Connections** in the left sidebar

2. Click **Create a connection**

3. Select the **Connection Type** from the dropdown:
   * REST - Basic Authentication
   * REST - Bearer Token
   * REST - API Key
   * AWS
   * Salesforce
   * Redis
   * And more...

4. Configure environment-specific settings:

| Setting | QA Environment | Production Environment |
| - | - | - |
| **Base URL** | `https://api.staging.example.com` | `https://api.example.com` |
| **Credentials** | Test/sandbox credentials | Production credentials |

5. Click **Save**

> [!TIP]
>
> Create connections once, use them across multiple workflows. When credentials change, update the connection—all workflows using it are automatically updated.

### Example: Snapsheet Connection

| Setting | QA | Production |
| - | - | - |
| **Name** | Snapsheet Claims API | Snapsheet Claims API |
| **Type** | REST - Bearer Token | REST - Bearer Token |
| **Base URL** | `https://api.staging.snapsheet.com/v1` | `https://api.snapsheet.com/v1` |
| **Token** | `sk_test_xxxxx` | `sk_live_xxxxx` |

***

## Configuration

Click on a Task Node to open its configuration panel.

### Basic Settings

| Setting | Description | Example |
| - | - | - |
| **Title** | Descriptive name for the node | `Create Snapsheet Claim` |
| **Connection** | Select a pre-configured connection | `Snapsheet Claims API` |
| **Method** | HTTP method for the request | `POST`, `GET`, `PUT`, `DELETE`, `PATCH` |
| **URL** | Endpoint path (appended to base URL) | `/claims` |

**Full URL construction:**

```
Base URL (from Connection) + URL (from Task Node) = Final URL

https://api.snapsheet.com/v1 + /claims = https://api.snapsheet.com/v1/claims
```

### HTTP Methods

| Method | Use Case | Example |
| - | - | - |
| **GET** | Retrieve data | Look up policy details |
| **POST** | Create new records | Submit a new claim |
| **PUT** | Replace existing records | Update entire policy record |
| **PATCH** | Partial updates | Update just the address |
| **DELETE** | Remove records | Cancel a pending request |

***

## Request Transformation

Transform your workflow context into the format the API expects.

Click **+ Add request transformation** to configure:

### Structure

```json theme={null}
{
  "body": {
    // Request body - sent as JSON
  },
  "params": {
    // URL query parameters
  },
  "headers": {
    // Additional HTTP headers
  }
}
```

### Example: Create Claim Request

**Workflow context:**

```json theme={null}
{
  "claimType": "water",
  "claimDetails": "Basement flooded",
  "callerFirstName": "John",
  "callerLastName": "Smith",
  "policyNumber": "HO-12345678",
  "dateOfLoss": "2025-02-13"
}
```

**Request transformation (JSONata):**

```jsonata theme={null}
{
  "body": {
    "claim_type": $.claimType,
    "description": $.claimDetails,
    "policy_id": $.policyNumber,
    "loss_date": $.dateOfLoss,
    "reporter_name": $.callerFirstName & " " & $.callerLastName
  }
}
```

**Resulting HTTP request:**

```
POST https://api.snapsheet.com/v1/claims
Content-Type: application/json

{
  "claim_type": "water",
  "description": "Basement flooded",
  "policy_id": "HO-12345678",
  "loss_date": "2025-02-13",
  "reporter_name": "John Smith"
}
```

### Query Parameters

For GET requests or when APIs require query parameters:

```jsonata theme={null}
{
  "params": {
    "policy_number": $.policyNumber,
    "include_coverage": "true"
  }
}
```

**Results in:**

```
GET https://api.example.com/v1/policies?policy_number=HO-12345678&include_coverage=true
```

### Custom Headers

Add headers beyond what the connection provides:

```jsonata theme={null}
{
  "headers": {
    "X-Request-ID": $.correlationId,
    "X-Source": "liberate-voice-ai"
  },
  "body": {
    ...
  }
}
```

***

## Response Handling

Configure where to store the API response in your workflow context.

### Success Response

| Setting | Description |
| - | - |
| **Property** | Context key where successful response is stored |
| **Action expression** | Optional JSONata to transform the response |

**Example:**

Setting: `On Success → snapsheetResponse`

API returns:

```json theme={null}
{
  "claim_id": "CLM-98765",
  "status": "created",
  "created_at": "2025-02-13T14:30:00Z"
}
```

Context after Task Node:

```json theme={null}
{
  "claimType": "water",
  "policyNumber": "HO-12345678",
  "snapsheetResponse": {
    "claim_id": "CLM-98765",
    "status": "created",
    "created_at": "2025-02-13T14:30:00Z"
  }
}
```

### Error Response

| Setting | Description |
| - | - |
| **Property** | Context key where error response is stored |
| **Action expression** | Optional JSONata to transform the error |

**Example:**

Setting: `On Error → snapsheetError`

API returns (400 Bad Request):

```json theme={null}
{
  "error": "invalid_policy",
  "message": "Policy number not found"
}
```

Context after Task Node (error path):

```json theme={null}
{
  "policyNumber": "HO-INVALID",
  "snapsheetError": {
    "error": "invalid_policy",
    "message": "Policy number not found"
  }
}
```

***

## Response Transformation

Optionally transform the API response before storing it.

Click **+ Add response transformation** to configure:

```jsonata theme={null}
{
  "success": {
    "claimId": $.data.claim_id,
    "claimStatus": $.data.status
  },
  "error": {
    "errorCode": $.error.code,
    "errorMessage": $.error.message
  }
}
```

This extracts only the fields you need from potentially large API responses.

***

## Retry Strategy

Configure how the Task Node handles failed requests.

### Settings

| Setting | Description |
| - | - |
| **Retry Strategy** | How delay is calculated between retries |
| **Times** | Number of retry attempts before failing |
| **Delay (ms)** | Base delay between retries in milliseconds |
| **Status Codes** | Which HTTP status codes trigger a retry |

### Strategy Options

> [tab] Linear
>
> Constant delay between retries.
>
> **Example:** 3 retries, 1000ms delay
>
> ```
> Attempt 1 → Fail → Wait 1000ms
> Attempt 2 → Fail → Wait 1000ms
> Attempt 3 → Fail → Wait 1000ms
> Attempt 4 → Fail → Error path
> ```
>
> **Best for:** Consistent, predictable retry timing

> [tab] Exponential
>
> Increasing delay between retries (backs off).
>
> **Example:** 3 retries, 1000ms base delay
>
> ```
> Attempt 1 → Fail → Wait 1000ms
> Attempt 2 → Fail → Wait 2000ms
> Attempt 3 → Fail → Wait 4000ms
> Attempt 4 → Fail → Error path
> ```
>
> **Best for:** External APIs that may be temporarily overloaded

> [tab] None
>
> No retries—fail immediately.
>
> ```
> Attempt 1 → Fail → Error path
> ```
>
> **Best for:** Operations that shouldn't be retried (e.g., payments)

### Status Codes to Retry

Common status codes that indicate transient failures:

| Code | Meaning | Retry? |
| - | - | - |
| `500` | Internal Server Error | ✅ Yes |
| `502` | Bad Gateway | ✅ Yes |
| `503` | Service Unavailable | ✅ Yes |
| `504` | Gateway Timeout | ✅ Yes |
| `429` | Too Many Requests | ✅ Yes |
| `400` | Bad Request | ❌ No (fix the request) |
| `401` | Unauthorized | ❌ No (fix credentials) |
| `404` | Not Found | ❌ No (resource doesn't exist) |

**Recommended configuration:**

```
Status Codes: 500, 502, 503, 504, 429
```

***

## Error Handling

Every Task Node has **success** and **error** paths. Hover over the node to see:

* `+` — Success connector (green)
* `⚠` — Error connector (yellow/orange)

### Branching on Errors

```
Task Node (Create Claim)
    ├── Success → Mapping Node → End Node (return claim number)
    └── Error → Error Handler → End Node (return error message)
```

### Error Path Use Cases

| Scenario | Error Path Action |
| - | - |
| API validation error | Return message: "Please verify your policy number" |
| API unavailable | Escalate to human agent |
| Authentication failure | Log error, alert operations team |
| Timeout | Retry with different approach or escalate |

### Example: Return Error to Voice AI

On the error path, add a Mapping Node to format the error message:

```jsonata theme={null}
{
  "responseToVoiceAI": {
    "success": false,
    "message": snapsheetError.message ? snapsheetError.message : "Unable to process your request. Let me transfer you to an agent."
  }
}
```

***

## Insurance Examples

### Create Claim in Snapsheet

| Setting | Value |
| - | - |
| **Connection** | Snapsheet Claims API |
| **Method** | POST |
| **URL** | `/claims` |

**Request Transformation:**

```jsonata theme={null}
{
  "body": {
    "claim_type": $.claimType,
    "description": $.claimDetails,
    "policy_id": $.policyNumber,
    "loss_date": $.dateOfLoss,
    "reporter": {
      "name": $.callerFirstName & " " & $.callerLastName,
      "phone": $.callerPhone
    }
  }
}
```

**Response Handling:**

* On Success: `claimResponse`
* On Error: `claimError`

***

### Look Up Policy in Vertafore

| Setting | Value |
| - | - |
| **Connection** | Vertafore AMS360 API |
| **Method** | GET |
| **URL** | `/policies` |

**Request Transformation:**

```jsonata theme={null}
{
  "params": {
    "policy_number": $.policyNumber,
    "include": "coverages,insured"
  }
}
```

**Response Handling:**

* On Success: `policyData`
* On Error: `policyLookupError`

***

### Update Customer in Salesforce

| Setting | Value |
| - | - |
| **Connection** | Salesforce CRM |
| **Method** | PATCH |
| **URL** | `/sobjects/Contact/` & \$.salesforceContactId |

**Request Transformation:**

```jsonata theme={null}
{
  "body": {
    "Phone": $.newPhone,
    "MailingStreet": $.newAddress.street,
    "MailingCity": $.newAddress.city,
    "MailingState": $.newAddress.state,
    "MailingPostalCode": $.newAddress.zip
  }
}
```

***

### Log Activity in Applied Epic

| Setting | Value |
| - | - |
| **Connection** | Applied Epic API |
| **Method** | POST |
| **URL** | `/activities` |

**Request Transformation:**

```jsonata theme={null}
{
  "body": {
    "customer_id": $.customerId,
    "activity_type": "VOICE_AI_CALL",
    "description": "Voice AI handled " & $.callType & " request",
    "timestamp": $now(),
    "outcome": $.callOutcome
  }
}
```

***

## Best Practices

### Use Descriptive Names

| ❌ Bad | ✅ Good |
| - | - |
| Task | Create Snapsheet Claim |
| API Call | Look Up Policy in AMS360 |
| HTTP | Update Salesforce Contact |

### Always Handle Errors

Never leave the error path unconnected. At minimum:

* Log the error for debugging
* Return a user-friendly message to Voice AI
* Consider escalation to a human agent

### Set Appropriate Timeouts

For slow external APIs, ensure your retry strategy accounts for total time:

```
3 retries × (request time + 2000ms delay) = total time
```

If total time exceeds your workflow timeout, reduce retries or delays.

### Test with Real API Responses

Use Preview mode with realistic API responses (including error cases) to verify your response handling works correctly.

### Secure Your Connections

* Use different credentials for QA and Production
* Rotate credentials periodically
* Never hardcode credentials in transformations—always use Connections

***

## Common Issues

### 401 Unauthorized

**Symptom:** Task Node fails with 401 error.

**Fix:** Check your Connection credentials. Verify the token/API key hasn't expired.

### 400 Bad Request

**Symptom:** Task Node fails with 400 error.

**Fix:** Check your request transformation. The API is rejecting your request format. Review the API documentation for required fields.

### Timeout

**Symptom:** Task Node fails with timeout.

**Fix:**

* Increase retry delays
* Check if the external API is slow
* Consider async workflow execution

### Response Not in Context

**Symptom:** Can't access API response in subsequent nodes.

**Fix:** Verify you configured "On Success" and "On Error" properties. Check the property names match what you're referencing.

***

## Next Steps

> [card] [Connections Guide](https://docs.liberate.ai/workflows/concepts/connections.md)
>
> Learn more about setting up connections

> [card] [Mapping Node](https://docs.liberate.ai/workflows/nodes/mapping-node.md)
>
> Transform data before sending to APIs

> [card] [Error Handling](https://docs.liberate.ai/workflows/error-handling)
>
> Build robust error handling workflows

> [card] [Voice AI Workflows](https://docs.liberate.ai/workflows/voice-ai-workflows.md)
>
> See complete workflow examples


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.