TurfAITurfAI Developers
API Reference

TurfAI Task Types Reference

Synced from the TurfAI source on 2026-06-21.

Complete reference for all available task types in TurfAI workflows.


Overview

Task types are the building blocks of TurfAI workflows. Each task type performs a specific operation and can be connected to form complex automation pipelines.

API Endpoint: GET /api/workflows/task-types


Categories

CategoryDescriptionTask Types
AI OperationsML-powered document processingclassification, extraction, llm, summarization, classify_and_extract, rag_enable, rag_query
Google IntegrationsGoogle Drive/Gmail operationsgoogle_drive_fetch
External IntegrationsHTTP API callsrest_api
CommunicationEmail/notificationsemail_send
Workflow ControlFlow control primitivesdecision, wait

Core Integration Tasks

These are the most commonly used task types for workflow integrations.


google_drive_fetch_task

Fetch files from Google Drive and import to GCS.

Processor: google_drive_fetch

Use Cases:

  • Fetch job descriptions from shared folders
  • Download resumes submitted via forms
  • Import policy documents for RAG indexing

Configuration

{
  "task_type": "google_drive_fetch_task",
  "config": {
    "file_id": "1ABC123xyz"
  }
}

Config Options:

FieldTypeRequiredDescription
file_idstringOne ofDirect Google Drive file ID
folder_idstringOne ofFolder ID for search mode
file_namestringWith folder_idFile name to search for

Modes:

  1. Direct: Provide file_id to fetch specific file
  2. Search: Provide folder_id + file_name to find file in folder

Output

{
  "file_url": "gs://turfdms/documents/123/file.pdf",
  "file_id": "1ABC123xyz",
  "file_name": "Resume_JohnDoe.pdf",
  "mime_type": "application/pdf",
  "size": 245789,
  "document_id": 123
}

Example Node

{
  "id": "fetch-resume",
  "type": "google_drive_fetch_task",
  "data": {
    "label": "Fetch Resume from Drive",
    "task_type": "google_drive_fetch_task",
    "config": {
      "file_id": "{{resume_file_id}}"
    }
  }
}

rest_api_task

Make HTTP requests to external APIs with template variable support.

Processor: rest_api

Use Cases:

  • Fetch configuration from external services
  • Post results to external systems
  • Integrate with third-party APIs
  • Call internal TurfAI endpoints

Configuration

{
  "task_type": "rest_api_task",
  "config": {
    "url": "http://localhost:9005/roles/{{role_id}}",
    "method": "GET",
    "timeout": 30,
    "output_mapping": {
      "jd_file_id": "$.data.jd_file_id",
      "hiring_manager_email": "$.data.hiring_manager_email"
    }
  }
}

Config Options:

FieldTypeRequiredDefaultDescription
urlstringYes-API URL (supports {{variable}} templates)
methodstringNoGETHTTP method
headersobjectNo{}Request headers (supports templates)
bodyobjectNo-Request body for POST/PUT/PATCH
timeoutnumberNo30Timeout in seconds
output_mappingobjectNo-JSONPath mappings for response extraction

Template Variables

URLs, headers, and body values support {{variable}} syntax:

{
  "url": "https://api.example.com/users/{{user_id}}/documents",
  "headers": {
    "Authorization": "Bearer {{api_token}}"
  },
  "body": {
    "name": "{{candidate_name}}",
    "email": "{{email}}"
  }
}

Output Mapping (JSONPath)

Extract specific fields from the response:

{
  "output_mapping": {
    "extracted_name": "$.data.user.name",
    "first_item": "$.items[0].id",
    "nested_value": "$.response.metadata.count"
  }
}

Output

{
  "data": {
    "jd_file_id": "1ABC123xyz",
    "hiring_manager_email": "manager@company.com"
  },
  "status_code": 200,
  "_raw_response": { ... }
}

Example: Fetch Role Configuration

{
  "id": "fetch-role-config",
  "type": "rest_api_task",
  "data": {
    "label": "Fetch Role Configuration",
    "task_type": "rest_api_task",
    "config": {
      "url": "http://localhost:9005/roles/{{role_id}}",
      "method": "GET",
      "output_mapping": {
        "jd_file_id": "$.data.jd_file_id",
        "hiring_manager_email": "$.data.hiring_manager_email",
        "hr_email": "$.data.hr_email"
      }
    }
  }
}

email_send_task

Send emails with HTML support and template variables.

Processor: email_send

Use Cases:

  • Send job match notifications
  • Deliver workflow results
  • Send policy update confirmations
  • Notify stakeholders

Configuration

{
  "task_type": "email_send_task",
  "config": {
    "to": ["{{hiring_manager_email}}", "hr@company.com"],
    "cc": ["{{recruiter_email}}"],
    "subject": "New Application: {{candidate_name}} for {{position}}",
    "body": "<h2>Application Received</h2><p>Candidate: {{candidate_name}}</p><p>Match Score: {{match_score}}%</p>",
    "html": true
  }
}

Config Options:

FieldTypeRequiredDefaultDescription
fromstringNoSystem defaultSender email
toarrayYes-Recipient emails (supports templates)
ccarrayNo[]CC recipients
bccarrayNo[]BCC recipients
subjectstringYes-Email subject (supports templates)
bodystringYes-Email body (supports templates)
htmlbooleanNotrueSend as HTML

Output

{
  "sent": true,
  "recipients": ["manager@company.com", "hr@company.com"],
  "timestamp": "2024-11-24T10:30:00.000Z"
}

Example: Notification Email

{
  "id": "send-notification",
  "type": "email_send_task",
  "data": {
    "label": "Send Match Notification",
    "task_type": "email_send_task",
    "config": {
      "to": ["{{hiring_manager_email}}"],
      "subject": "New Application Match: {{candidate_name}}",
      "body": "<h2>New Job Application</h2><p><strong>Candidate:</strong> {{candidate_name}}</p><p><strong>Position:</strong> {{position}}</p><p><strong>Match Score:</strong> {{match_score}}%</p><h3>Summary</h3><p>{{ai_summary}}</p>",
      "html": true
    }
  }
}

wait_task

Poll an endpoint until a condition is met. Generic async wait primitive.

Processor: wait

Use Cases:

  • Wait for RAG indexing to complete
  • Poll external job status
  • Wait for approval workflows
  • Monitor async processing

Configuration

{
  "task_type": "wait_task",
  "config": {
    "endpoint": "/api/internal/documents/{{document_id}}/rag-status",
    "method": "GET",
    "watch_field": "rag_processing_status",
    "success_value": "completed",
    "failure_values": ["failed", "error"],
    "poll_interval": 3,
    "timeout": 120
  }
}

Config Options:

FieldTypeRequiredDefaultDescription
endpointstringYes-URL to poll (supports templates)
methodstringNoGETHTTP method
watch_fieldstringYes-Field to monitor (dot notation supported)
success_valuestringNo"completed"Value indicating success
failure_valuesarrayNo["failed", "error"]Values indicating failure
poll_intervalnumberNo3Seconds between polls
timeoutnumberNo120Maximum wait time in seconds

Output

{
  "status": "success",
  "final_value": "completed",
  "response": { ... },
  "elapsed_seconds": 45
}

Example: Wait for RAG Indexing

{
  "id": "wait-for-rag",
  "type": "wait_task",
  "data": {
    "label": "Wait for RAG Completion",
    "task_type": "wait_task",
    "config": {
      "endpoint": "/api/internal/documents/{{document_id}}/rag-status",
      "watch_field": "rag_processing_status",
      "success_value": "completed",
      "failure_values": ["failed"],
      "poll_interval": 5,
      "timeout": 300
    }
  }
}

AI Operations Tasks


classification_task

Classify documents into categories using AI.

Processor: classification

Configuration

FieldTypeDefaultDescription
classification_typestring"document_type"Type: document_type, sentiment, topic
include_confidencebooleantrueInclude confidence scores
return_multiplebooleanfalseReturn multiple classifications

Input

FieldTypeRequiredDescription
file_urlstringYesGCS URL of document
metadataobjectNoAdditional context

Output

{
  "prompt_title": "Resume Classification",
  "section": "HR Documents",
  "confidence": 0.95,
  "classification": {
    "type": "resume",
    "subtype": "technical"
  }
}

extraction_task

Extract structured data from documents.

Processor: document_extraction

Configuration

FieldTypeDefaultDescription
prompt_idstring-Prompt ID to use
model_typestring"vertex"LLM: vertex, openai, anthropic
output_formatstring"json"Output: json, text
use_classification_promptbooleanfalseUse prompt from classification

Input

FieldTypeRequiredDescription
file_urlstringYesGCS URL of document
prompt_dataobjectNoPrompt override

Output

{
  "extraction_result": {
    "name": "John Doe",
    "email": "john@example.com",
    "skills": ["Python", "Machine Learning"],
    "experience_years": 5
  },
  "confidence": 0.92,
  "tokens_used": 1250
}

llm_task

Generic LLM-powered text processing.

Processor: llm_task

Configuration

FieldTypeDefaultDescription
prompt_idstring-Use predefined prompt
prompt_textstring-Custom prompt text
model_typestring"vertex"LLM provider
process_combined_inputsbooleantrueCombine all inputs
output_formatstring"json"Output format

Input

FieldTypeRequiredDescription
file_urlstringNoDocument URL
prompt_dataobjectNoPrompt variables
text_inputstringNoDirect text input

Output

{
  "result": { ... },
  "tokens_used": 850
}

summarization_task

Generate document summaries.

Processor: summarization

Configuration

FieldTypeDefaultDescription
summary_typestring"brief"Type: brief, detailed, bullet_points
max_lengthnumber500Max words

Output

{
  "summary": "This resume belongs to a senior software engineer with 5 years of experience in Python and machine learning...",
  "word_count": 150
}

classify_and_extract

Combined classification and extraction in one step.

Processor: classify_and_extract

Configuration

FieldTypeDefaultDescription
classification_typestring"document_type"Classification type
extract_after_classifybooleantrueRun extraction after

Output

{
  "classification": {
    "type": "resume",
    "confidence": 0.95
  },
  "extraction_result": {
    "name": "John Doe",
    "skills": ["Python", "ML"]
  }
}

rag_enable_task

Enable RAG indexing for a document.

Processor: rest_api (calls internal endpoint)

Configuration

Default configuration calls /api/internal/rag/enable:

{
  "url": "http://localhost:1338/api/internal/rag/enable",
  "method": "POST",
  "body": {
    "document_id": "{{document_id}}",
    "user_id": "{{user_id}}",
    "force_reprocess": false
  }
}

Input

FieldTypeRequiredDescription
document_idnumberYesFrom previous node (e.g., drive fetch)
user_idnumberYesFrom workflow context

Output

{
  "rag_status": "queued",
  "rag_job_id": "rag-embed-123-1700000000"
}

rag_query_task

Query the RAG knowledge base.

Processor: rest_api (calls internal endpoint)

Configuration

Default configuration calls /api/internal/rag/query:

{
  "url": "http://localhost:1338/api/internal/rag/query",
  "method": "POST",
  "body": {
    "query": "{{query}}",
    "user_id": "{{user_id}}",
    "top_k": 5
  }
}

Input

FieldTypeRequiredDescription
querystringYesSearch query
user_idnumberYesFrom workflow context

Output

{
  "answer": "According to the Remote Work Policy document, employees can work remotely up to 3 days per week...",
  "sources": [
    {
      "document_id": 45,
      "document_name": "Remote Work Policy.pdf",
      "snippet": "...employees may work from home up to three days...",
      "score": 0.92
    }
  ],
  "session_id": "sess-abc123"
}

Workflow Examples

F1: Job Application Notification

{
  "nodes": [
    {
      "id": "1",
      "type": "rest_api_task",
      "data": {
        "label": "Fetch Role Config",
        "config": {
          "url": "http://localhost:9005/roles/{{role_id}}",
          "output_mapping": {
            "jd_file_id": "$.data.jd_file_id",
            "hiring_manager_email": "$.data.hiring_manager_email"
          }
        }
      }
    },
    {
      "id": "2",
      "type": "google_drive_fetch_task",
      "data": {
        "label": "Fetch JD",
        "config": { "file_id": "{{jd_file_id}}" }
      }
    },
    {
      "id": "3",
      "type": "google_drive_fetch_task",
      "data": {
        "label": "Fetch Resume",
        "config": { "file_id": "{{resume_file_id}}" }
      }
    },
    {
      "id": "4",
      "type": "extraction_task",
      "data": {
        "label": "Extract Resume",
        "config": { "output_format": "json" }
      }
    },
    {
      "id": "5",
      "type": "llm_task",
      "data": {
        "label": "Calculate Match",
        "config": {
          "prompt_text": "Compare this resume to the job description and provide a match score..."
        }
      }
    },
    {
      "id": "6",
      "type": "email_send_task",
      "data": {
        "label": "Notify Hiring Manager",
        "config": {
          "to": ["{{hiring_manager_email}}"],
          "subject": "New Application: {{candidate_name}}",
          "body": "<h2>Match Score: {{match_score}}%</h2>..."
        }
      }
    }
  ]
}

F4-A: HR Policy Ingestion

{
  "nodes": [
    {
      "id": "1",
      "type": "google_drive_fetch_task",
      "data": {
        "label": "Fetch Policy Doc",
        "config": { "file_id": "{{policy_file_id}}" }
      }
    },
    {
      "id": "2",
      "type": "rag_enable_task",
      "data": {
        "label": "Enable RAG"
      }
    },
    {
      "id": "3",
      "type": "wait_task",
      "data": {
        "label": "Wait for Indexing",
        "config": {
          "endpoint": "/api/internal/documents/{{document_id}}/rag-status",
          "watch_field": "rag_processing_status",
          "success_value": "completed",
          "timeout": 300
        }
      }
    },
    {
      "id": "4",
      "type": "email_send_task",
      "data": {
        "label": "Send Confirmation",
        "config": {
          "to": ["{{notification_email}}"],
          "subject": "Policy Indexed: {{policy_name}}",
          "body": "The policy document has been indexed and is now searchable."
        }
      }
    }
  ]
}

F4-B: Employee Q&A

{
  "nodes": [
    {
      "id": "1",
      "type": "rag_query_task",
      "data": {
        "label": "Query Knowledge Base",
        "config": {
          "body": {
            "query": "{{question}}",
            "user_id": "{{user_id}}",
            "top_k": 5
          }
        }
      }
    },
    {
      "id": "2",
      "type": "email_send_task",
      "data": {
        "label": "Send Answer",
        "config": {
          "to": ["{{employee_email}}"],
          "subject": "Answer to your question",
          "body": "<p>{{answer}}</p><h3>Sources</h3>{{sources}}"
        }
      }
    }
  ]
}

Template Variables

All task types support {{variable}} template syntax for dynamic values.

Sources of Variables

  1. Webhook Payload: Data sent to trigger endpoint
  2. Previous Node Outputs: Results from upstream nodes
  3. Workflow Context: user_id, execution_id, etc.

Example Flow

Webhook payload: { "candidate_name": "John", "role_id": "engineer" }

Node 1 (rest_api_task): Uses {{role_id}} → outputs { "jd_file_id": "ABC123" }

Node 2 (google_drive_fetch_task): Uses {{jd_file_id}} → outputs { "file_url": "gs://..." }

Node 3 (email_send_task): Uses {{candidate_name}}, {{file_url}}

Error Handling

Task Failure

When a task fails, the workflow execution status becomes failed:

{
  "status": "failed",
  "error": "REST API call failed: 404 Not Found",
  "failed_node": "fetch-role-config",
  "task_states": {
    "fetch-role-config": {
      "status": "failed",
      "error": "404 Not Found"
    }
  }
}

Timeout Handling

The wait_task returns failure status on timeout:

{
  "status": "failure",
  "final_value": "processing",
  "elapsed_seconds": 120,
  "error": "Timeout waiting for completion"
}

Control Flow Tasks

decision

NEW in v1.1 - Conditional branching based on runtime evaluation.

Evaluates a condition and directs workflow execution down one of two paths (true or false). Enables dynamic workflow behavior based on previous task outputs.

Processor: decision (alias: decision_task)

Use Cases:

  • Route documents based on classification results
  • Handle different document types with separate processing paths
  • Conditional approval workflows
  • Dynamic email routing based on content analysis
  • Skip processing steps based on validation results

Configuration

{
  "task_type": "decision",
  "config": {
    "operator": "==",
    "left_operand": "$.classification.type",
    "right_operand": "Invoice",
    "true_label": "true",
    "false_label": "false"
  }
}

Config Options:

FieldTypeRequiredDescription
operatorstringYesComparison operator: ==, !=, >, <, >=, <=, in, contains, matches
left_operandstringYesJSONPath expression (e.g., $.classification.type) or literal value
right_operandstring/number/booleanYesValue to compare against (can be literal or JSONPath)
true_labelstringNoLabel for true path (default: "true")
false_labelstringNoLabel for false path (default: "false")

Supported Operators:

OperatorDescriptionExample
==Equals$.type == "Invoice"
!=Not equals$.status != "processed"
>Greater than$.amount > 1000
<Less than$.confidence < 0.8
>=Greater or equal$.score >= 90
<=Less or equal$.priority <= 5
inLeft in right (array/string)"pdf" in $.allowed_types
containsRight in left (array/string)$.tags contains "urgent"
matchesRegex match$.email matches ".*@company.com"

JSONPath Support

Use JSONPath expressions to reference outputs from previous tasks:

$.task_name.field_name

Examples:

  • $.classification.type - Access classification result
  • $.extraction.invoice_amount - Access extracted field
  • $.email.to - Access email configuration
  • Literal values: "Invoice", 1000, true

Output

{
  "result": true,
  "branch": "true",
  "decision": "true",
  "active_path": "true",
  "condition": {
    "operator": "==",
    "left_operand": "$.classification.type",
    "right_operand": "Invoice",
    "left_value": "Invoice",
    "right_value": "Invoice"
  }
}

Output Fields:

FieldTypeDescription
resultbooleanCondition evaluation result
branchstringSelected branch label
decisionstring"true" or "false"
active_pathstringPath taken by execution
conditionobjectDetails about evaluated condition

Edge Configuration

Decision nodes MUST have exactly 2 outgoing edges:

  1. True Edge: Label = "true" (or custom true_label)
  2. False Edge: Label = "false" (or custom false_label)

Frontend: When connecting edges from a decision node:

  1. Click the edge to select it
  2. Set the edge label property to "true" or "false"
  3. The workflow executor uses this label to activate/deactivate paths

Example: Document Type Routing

{
  "nodes": [
    {
      "id": "classify",
      "type": "classification_task",
      "data": {
        "label": "Classify Document",
        "task_type": "classification_task",
        "config": {
          "category": "document_type"
        }
      }
    },
    {
      "id": "decision",
      "type": "decision",
      "data": {
        "label": "Is Invoice?",
        "task_type": "decision",
        "config": {
          "operator": "==",
          "left_operand": "$.classify.type",
          "right_operand": "Invoice"
        }
      }
    },
    {
      "id": "process-invoice",
      "type": "extraction_task",
      "data": {
        "label": "Extract Invoice Data",
        "task_type": "extraction_task",
        "config": {
          "prompt_id": 42
        }
      }
    },
    {
      "id": "process-other",
      "type": "summarization_task",
      "data": {
        "label": "Summarize Document",
        "task_type": "summarization_task",
        "config": {
          "type": "brief"
        }
      }
    }
  ],
  "edges": [
    { "source": "classify", "target": "decision" },
    {
      "source": "decision",
      "target": "process-invoice",
      "sourceHandle": "true",
      "label": "true"
    },
    {
      "source": "decision",
      "target": "process-other",
      "sourceHandle": "false",
      "label": "false"
    }
  ]
}

Workflow Execution Behavior

  1. Decision node executes - Evaluates condition
  2. Edge activation - Marks one edge as active based on result
  3. Path execution - Only nodes on active path execute
  4. Skipped nodes - Nodes on inactive path get status: "skipped"
  5. Convergence - Paths can merge back together downstream

Important: The workflow remains a DAG (Directed Acyclic Graph). Decision nodes create diverging paths, not loops.

Advanced Examples

Numeric Comparison:

{
  "operator": ">",
  "left_operand": "$.extraction.invoice_amount",
  "right_operand": "10000"
}

Array Contains:

{
  "operator": "contains",
  "left_operand": "$.classification.tags",
  "right_operand": "urgent"
}

Regex Match:

{
  "operator": "matches",
  "left_operand": "$.extraction.email",
  "right_operand": ".*@approved-domain\\.com$"
}

Nested Field Access:

{
  "operator": "==",
  "left_operand": "$.rest_api.response.data.status",
  "right_operand": "approved"
}

Validation Rules

Backend validation (workflow-validation.js) enforces:

  1. Decision nodes must have exactly 2 outgoing edges
  2. Both edges must have labels
  3. One edge must be labeled "true", one "false"
  4. Config must include: operator, left_operand, right_operand

Validation errors will prevent workflow execution.

Frontend Component

  • Node Type: Diamond-shaped with orange gradient
  • Handles:
    • Top: Target (incoming)
    • Left: Source (true path, green)
    • Right: Source (false path, red)
  • Config Panel: Dropdown operators, JSONPath hints, condition preview

Limitations (Phase 1)

  • ⚠️ No loops: Workflow must remain acyclic (no cycles allowed)
  • ⚠️ Binary branches: Only true/false (multi-way branching not supported)
  • ⚠️ Simple conditions: No AND/OR/NOT logic (single comparison only)

Workaround for complex conditions: Chain multiple decision nodes


See Also

On this page