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

# Workflows

> n8n workflow structure, mandatory Codika node patterns, and workflow JSON conventions

## Mandatory workflow pattern

Every parent workflow (not sub-workflows) **must** follow this structure:

```
Trigger → Codika Init → [Business Logic] → IF (success?)
                                             ├── Yes → Codika Submit Result
                                             └── No  → Codika Report Error
```

Without these nodes:

* **Missing Codika Init**: Platform cannot track execution, credentials unavailable
* **Missing Submit/Report**: Execution shows as "pending" forever, user sees no feedback

Sub-workflows start with `Execute Workflow Trigger` and do **not** include Codika Init, Submit Result, or Report Error nodes.

## Codika nodes

These are custom n8n nodes that integrate workflows with the Codika platform. They use the node type `n8n-nodes-codika.codika` in workflow JSON.

### Codika Init (`initWorkflow`)

First node after the trigger in all parent workflows. Two modes depending on trigger type:

**HTTP triggers** — extracts execution metadata from the webhook payload:

```json theme={null}
{
  "type": "n8n-nodes-codika.codika",
  "typeVersion": 1,
  "parameters": {
    "resource": "processManagement",
    "operation": "initWorkflow"
  }
}
```

**Schedule and service event triggers** — creates the execution by calling the platform API:

```json theme={null}
{
  "type": "n8n-nodes-codika.codika",
  "typeVersion": 1,
  "parameters": {
    "resource": "processManagement",
    "operation": "initWorkflow",
    "memberSecret": "{{MEMSECRT_EXECUTION_AUTH_TRCESMEM}}",
    "organizationId": "{{USERDATA_ORGANIZATION_ID_ATADRESU}}",
    "userId": "{{USERDATA_USER_ID_ATADRESU}}",
    "processInstanceId": "{{USERDATA_PROCESS_INSTANCE_UID_ATADRESU}}",
    "workflowId": "my-workflow-id",
    "triggerType": "schedule"
  }
}
```

**Outputs:** `executionId`, `executionSecret`, `callbackUrl`, `processId`, `userId`, `workflowId`

### Codika Submit Result (`submitResult`)

End of success paths. Sends structured result data back to the platform.

```json theme={null}
{
  "type": "n8n-nodes-codika.codika",
  "typeVersion": 1,
  "parameters": {
    "resource": "processManagement",
    "operation": "submitResult",
    "resultData": "={{ JSON.stringify($json.results) }}"
  }
}
```

The `resultData` must be a JSON string matching the workflow's `outputSchema`.

### Codika Report Error (`reportError`)

End of error/failure paths. Reports the error to the platform.

```json theme={null}
{
  "type": "n8n-nodes-codika.codika",
  "typeVersion": 1,
  "parameters": {
    "resource": "processManagement",
    "operation": "reportError",
    "errorMessage": "={{ $json.error.message }}",
    "errorType": "node_failure"
  }
}
```

Error types: `node_failure`, `validation_error`, `external_api_error`, `timeout`

### Codika Upload File (`uploadFile`)

Uploads files generated by the workflow (PDFs, images, videos) to platform storage.

```json theme={null}
{
  "type": "n8n-nodes-codika.codika",
  "typeVersion": 1,
  "parameters": {
    "resource": "fileManagement",
    "operation": "uploadFile"
  }
}
```

Returns a `documentId` that can be included in the output schema as a `file` type field.

**In sub-workflows**, you must pass execution metadata explicitly:

```json theme={null}
{
  "parameters": {
    "resource": "fileManagement",
    "operation": "uploadFile",
    "executionIdOverride": "={{ $('Execute Workflow Trigger').first().json.executionId }}",
    "executionSecretOverride": "={{ $('Execute Workflow Trigger').first().json.executionSecret }}"
  }
}
```

## Workflow JSON structure

A valid n8n workflow JSON file contains:

```json theme={null}
{
  "name": "My Workflow",
  "nodes": [
    {
      "parameters": { },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [200, 300],
      "id": "unique-node-id",
      "name": "Webhook Trigger",
      "webhookId": "{{USERDATA_PROCESS_INSTANCE_UID_ATADRESU}}"
    }
  ],
  "connections": {
    "Webhook Trigger": {
      "main": [
        [{ "node": "Codika Init", "type": "main", "index": 0 }]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "errorWorkflow": "{{ORGSECRET_ERROR_WORKFLOW_ID_TERCESORG}}",
    "timezone": "Europe/Brussels"
  }
}
```

### Required settings

| Setting          | Value                                         | Purpose                        |
| ---------------- | --------------------------------------------- | ------------------------------ |
| `executionOrder` | `"v1"`                                        | Use n8n v1 execution order     |
| `errorWorkflow`  | `"{{ORGSECRET_ERROR_WORKFLOW_ID_TERCESORG}}"` | Platform error handler         |
| `timezone`       | e.g., `"Europe/Brussels"`                     | Timezone for schedule triggers |

### Fields to remove before committing

These are n8n internal fields that must be stripped from workflow JSON:

* `id` (top-level workflow ID)
* `versionId`
* `meta`
* `active`
* `tags`
* `pinData`

The `codika verify` command checks for these via the `workflow-sanitization` rule and can auto-fix with `--fix`.

## Common n8n node types

| Node type                                         | Purpose            | Example usage                   |
| ------------------------------------------------- | ------------------ | ------------------------------- |
| `n8n-nodes-base.webhook`                          | HTTP trigger       | Receive form submissions        |
| `n8n-nodes-base.scheduleTrigger`                  | Cron trigger       | Daily/weekly automation         |
| `n8n-nodes-base.executeWorkflowTrigger`           | Sub-workflow entry | Receive data from parent        |
| `n8n-nodes-base.executeWorkflow`                  | Call sub-workflow  | Delegate to helper workflow     |
| `n8n-nodes-base.code`                             | JavaScript/Python  | Custom data transformation      |
| `n8n-nodes-base.if`                               | Conditional        | Branch on success/failure       |
| `n8n-nodes-base.httpRequest`                      | HTTP client        | Call external APIs              |
| `n8n-nodes-base.gmail`                            | Gmail operations   | Read/send/label emails          |
| `@n8n/n8n-nodes-langchain.chainLlm`               | LLM chain          | Structured AI output            |
| `@n8n/n8n-nodes-langchain.agent`                  | AI agent           | Multi-step reasoning with tools |
| `@n8n/n8n-nodes-langchain.lmChatAnthropic`        | Claude model       | AI model configuration          |
| `@n8n/n8n-nodes-langchain.outputParserStructured` | Output parser      | Parse LLM JSON output           |

## Critical rules

1. **Never use Merge node before Codika terminal nodes** — causes deadlock on conditional branches
2. **All execution paths must end with Submit Result or Report Error** — no dead ends
3. **HTTP trigger `responseMode` must be `lastNode`** — ensures Codika Submit Result returns data properly
4. **Error handling in IF nodes** — every IF must have both True and False branches handled
5. **Access trigger data correctly** — use `$('Trigger Name').first().json`, not via Codika Init output
