# Builder Agents Source: https://doc.codika.io/builder/agents Detailed reference for the four agents that create, modify, build, and test Codika use cases ## Which agent should I use? | I want to... | Use this agent | | ----------------------------------------------------------------- | ------------------------ | | Create a new use case from a business requirement | **use-case-builder** | | Add a feature, change a trigger, or refactor an existing use case | **use-case-modifier** | | Build a single workflow JSON file (not a full use case) | **n8n-workflow-builder** | | Deploy, test, and fix a use case end-to-end | **use-case-tester** | ## use-case-builder The main architect agent. Give it a business goal and it designs and creates a complete use case from scratch. **What it does:** 1. **Understands your goal** — extracts the core business intent from your description. You don't need to specify triggers, placeholders, or implementation details — the agent decides those. 2. **Reads platform documentation** — always reads the use-case guide, config patterns, and Codika nodes guide. Reads trigger-specific and integration guides based on the architecture it designs. 3. **Researches similar use cases** — searches the workspace for reference implementations and plan examples. 4. **Presents an architecture plan** — shows you the proposed workflows, triggers, integrations, and deployment parameters before building anything. 5. **Creates the folder structure** — scaffolds the use case with `config.ts`, `version.json`, and the workflows directory. 6. **Delegates workflow creation** — invokes the `n8n-workflow-builder` agent for each workflow, providing it with the full specification. 7. **Validates everything** — runs `codika verify use-case` to catch issues before you deploy. **Example prompts:** ``` "I want to automate invoice processing. Users upload PDFs and get structured data back." "We need something that monitors our Gmail for new client emails and logs them in Google Sheets with an AI summary." "I need daily reports from our Supabase database sent to Slack." ``` The builder handles all implementation decisions — trigger types, credential scopes, placeholder patterns, sub-workflow extraction. Describe the **what**, not the **how**. ## use-case-modifier Modifies, extends, or refactors existing use cases. Reads the current architecture before making any changes. **What it does:** 1. **Reads the entire use case** — config.ts, all workflow JSON files, project.json. Summarizes the current architecture for your confirmation. 2. **Reads relevant documentation** — always reads use-case-guide.md and config-patterns.md. Reads additional guides based on the modification (e.g., sub-workflow guide if extracting logic). 3. **Plans modifications** — specifies which files will be modified, created, or deleted. Includes a risk assessment for breaking changes. 4. **Makes targeted edits** — modifies existing workflow JSON with surgical edits. Delegates new workflow creation to `n8n-workflow-builder`. Updates config.ts to reflect all changes. 5. **Validates thoroughly** — checks that existing workflows still pass validation after changes. **Example prompts:** ``` "Add a Slack notification workflow to the invoice-processor use case." "Change the invoice-processor from HTTP trigger to a Gmail trigger." "The main workflow in customer-onboarding is too complex. Extract the email validation part into a sub-workflow." ``` The modifier always reads and understands the existing use case before making any changes. It will not blindly add or remove code — it plans first, then acts. ## n8n-workflow-builder Builds individual n8n workflow JSON files. Called by the other agents, but can also be invoked directly for single-workflow tasks. **What it does:** 1. **Reads documentation** — trigger-specific guide, Codika nodes guide, and any relevant integration guides. 2. **Researches similar workflows** — searches existing use cases for reference implementations. 3. **Builds the workflow JSON** — creates a complete, valid n8n workflow with correct node types, connections, placeholder usage, credential configuration, and node positioning. 4. **Validates before output** — runs through a 20+ item checklist covering trigger types, Codika patterns, placeholder suffixes, connection integrity, and more. **Mandatory patterns it enforces:** For parent workflows: ``` Trigger → Codika Init → Business Logic → IF (success?) ├─ Yes → Codika Submit Result └─ No → Codika Report Error ``` For sub-workflows: ``` Execute Workflow Trigger → Business Logic → Return Output ``` **Key rules:** * Credentials go on the **model node** (e.g., `lmChatAnthropic`), never on `chainLlm` or `agent` * Placeholder suffixes are the type name reversed: `FLEXCRED` → `_DERCXELF` * Every IF node must have both branches connected * Sub-workflows must have at least 1 input parameter * No hardcoded IDs or secrets — everything uses placeholders * Node positioning follows standard spacing (200px horizontal, 150px vertical) ## use-case-tester Tests and debugs use cases through automated deploy-trigger-inspect-fix loops. **What it does:** 1. **Verifies prerequisites** — checks the use case folder exists and passes validation. 2. **Deploys** — uses `codika deploy use-case` to push to the platform. 3. **Triggers each workflow** — constructs test payloads from `inputSchema` definitions and fires HTTP-triggered workflows. For schedule-triggered workflows, checks for manual trigger URLs. 4. **Inspects results** — on success, verifies output matches `outputSchema`. On failure, fetches the node-by-node execution trace with `codika get execution --deep --slim`. 5. **Diagnoses failures** — maps error patterns to root causes using a built-in diagnostic table covering 10+ common failure types. 6. **Fixes issues** — edits workflow JSON or config.ts directly. For complex rewrites, delegates to `n8n-workflow-builder`. 7. **Re-validates and deploys** — runs verify before each deploy. 8. **Repeats** — up to 5 iterations. If still failing, escalates with a clear diagnosis of what's wrong and what was tried. **Testing order:** 1. Sub-workflows first (no external dependencies) 2. Independent parent workflows 3. Workflow chains (parent → sub-workflow) 4. Edge cases (empty inputs, missing optional fields, error paths) **Common failures it diagnoses:** | Error pattern | Root cause | | ----------------------- | ----------------------------------------------------------------- | | credential not found | Wrong placeholder suffix or missing `integrationUid` in config.ts | | Cannot read properties | Incorrect expression referencing a previous node | | Codika Init failed | Missing `MEMSECRT` placeholder or wrong webhook path | | resultData key mismatch | Output doesn't match `outputSchema` definition | | Workflow not found | Broken `SUBWKFL` placeholder reference | | AI returns unstructured | Should use `chainLlm` instead of `agent` for structured output | After 5 failed iterations, the tester doesn't silently give up. It presents a clear diagnosis of what's still failing, what it tried, and what the user should investigate (e.g., missing credentials, external API issues). ## How agents delegate to each other ``` use-case-builder └─ calls n8n-workflow-builder (for each workflow in the new use case) use-case-modifier └─ calls n8n-workflow-builder (for any new workflows added during modification) use-case-tester └─ calls n8n-workflow-builder (for complex workflow rewrites during fix cycles) n8n-workflow-builder └─ standalone (does not delegate) ``` All agents use CLI skills from the `codika` plugin for platform operations: * **use-case-builder** → `codika:init-use-case`, `codika:verify-use-case` * **use-case-modifier** → `codika:verify-use-case` * **use-case-tester** → `codika:deploy-use-case`, `codika:trigger-workflow`, `codika:list-executions`, `codika:get-execution`, `codika:verify-use-case` # Builder System Source: https://doc.codika.io/builder/overview Autonomous AI agents that create, modify, and test Codika use cases from natural language requirements ## What is the Builder System? The Builder System ships inside the [`codika-io/plugin`](https://github.com/codika-io/plugin) agent plugin — an [Open Plugin v1](https://github.com/vercel-labs/open-plugin-spec)-conformant repo installable into any compatible coding agent (Claude Code, Cursor, …) with `npx plugins add codika-io/plugin`. It gives the agent the ability to autonomously design, build, modify, and test Codika use cases. Instead of manually writing `config.ts` files and n8n workflow JSON, you describe what you need in plain language and the agents handle the rest. The system reads the same platform documentation you do, designs the architecture, creates all files, validates them, deploys to the platform, and iteratively fixes any issues — all without requiring you to understand n8n internals or Codika patterns. ## How it works ``` You describe a business goal → use-case-builder reads platform docs, designs architecture → n8n-workflow-builder creates each workflow JSON → use-case-tester deploys, triggers, inspects, fixes → Production-ready use case ``` The system follows a **read-first, build-second** approach. Before creating anything, agents read the relevant platform guides (trigger types, credential patterns, integration specifics) to ensure every workflow follows Codika's mandatory patterns and placeholder conventions. ## The agents Four specialized agents work together, each handling a different phase of the lifecycle: | Agent | What it does | When to use | | ------------------------ | --------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | | **use-case-builder** | Creates new use cases from scratch — designs architecture, creates config.ts, delegates workflow creation | "I need an automation that does X" | | **use-case-modifier** | Modifies existing use cases — reads current state, plans changes, makes targeted edits | "Add Slack notifications to this use case" | | **n8n-workflow-builder** | Builds individual n8n workflow JSON files with correct patterns, placeholders, and node positioning | "Build a workflow that calls the Tavily API" | | **use-case-tester** | Tests and debugs through deploy-trigger-inspect-fix loops (max 5 iterations) | "Test the invoice-processor and fix any issues" | See [Builder Agents](/builder/agents) for detailed documentation on each agent. ## The discover-codika-guides skill All agents rely on a bundled skill called `discover-codika-guides` that ships with the complete Codika platform documentation. This means agents can read the right guides at runtime without needing access to the `codika-processes-lib` repository. The bundled documentation includes: * **Core guides** — use-case-guide.md, config-patterns.md, codika-nodes.md * **Trigger-specific guides** — HTTP triggers, schedule triggers, third-party triggers, sub-workflows * **Specialized guides** — AI nodes, placeholder patterns, deployment parameters, data ingestion, agent skills * **19 integration guides** — Anthropic, OpenAI, Google, Microsoft, Slack, Supabase, and more ## Prerequisites Before using the Builder System: 1. **Install the codika CLI** — `npm install -g codika` 2. **Authenticate** — `codika login` 3. **Install the codika plugin** — follow the [Codika Agent Plugin guide](/guides/claude-code-plugin) to install via `npx plugins add codika-io/plugin` ## Architecture The Builder System ships inside a single agent plugin (`codika-io/plugin`): | Component | What it provides | | --------------------------------------------- | ----------------------------------------------------------------------------------------------------- | | **Skills** (`/codika:*`) | 25 CLI skills — deploy, verify, trigger, fetch, manage integrations, discover platform docs, and more | | **Agents** (Task `subagent_type: "codika:*"`) | 4 builder agents — design, modify, build-workflow, test | The builder agents call the plugin's own skills for all platform operations. For example, `codika:use-case-tester` calls `codika:deploy-use-case` to deploy, `codika:trigger-workflow` to test, and `codika:get-execution` to inspect results. ## Next steps Understand each agent's capabilities and when to use them. See common workflows and tips for writing effective prompts. Plugin structure, bundled documentation catalog, and troubleshooting. Prefer building manually? Follow the step-by-step guide. # Builder Reference Source: https://doc.codika.io/builder/reference Plugin structure, bundled documentation catalog, agent invocation details, and troubleshooting ## Plugin structure The Builder System ships inside a single [Open Plugin v1](https://github.com/vercel-labs/open-plugin-spec) repo at [`codika-io/plugin`](https://github.com/codika-io/plugin). One plugin, 25 skills, 4 agents: ``` codika/ ├── .plugin/plugin.json # Vendor-neutral manifest (Open Plugin v1) ├── .claude-plugin/plugin.json # Claude Code preferred manifest ├── skills/ # 25 skills, namespaced `/codika:*` │ ├── setup-codika/ # Install and authenticate CLI │ ├── create-organization/ # Create organizations │ ├── create-organization-key/ # Create org API keys │ ├── update-organization-key/ # Update org API keys │ ├── create-project/ # Create projects │ ├── list-projects/ # List projects │ ├── get-project/ # Fetch project details │ ├── init-use-case/ # Scaffold new use cases │ ├── verify-use-case/ # Validate use cases │ ├── deploy-use-case/ # Deploy to platform │ ├── rerun-deployment/ # Rerun deployment with new params │ ├── publish-use-case/ # Promote to production │ ├── fetch-use-case/ # Download deployed use cases │ ├── deploy-documents/ # Upload stage documents │ ├── deploy-data-ingestion/ # Deploy RAG pipelines │ ├── trigger-workflow/ # Trigger workflows │ ├── get-execution/ # Debug execution traces │ ├── list-executions/ # List recent executions │ ├── list-instances/ # List process instances │ ├── get-instance/ # Fetch instance details │ ├── instance-activate/ # Activate/deactivate instances │ ├── manage-integrations/ # Configure credentials │ ├── manage-notes/ # Manage project notes │ ├── get-skills/ # List platform skills │ └── discover-codika-guides/ # Locate bundled platform docs │ └── references/ # Bundled platform documentation └── agents/ # 4 agents, Task `subagent_type: "codika:*"` ├── use-case-builder.md # Architect — creates new use cases ├── use-case-modifier.md # Surgeon — modifies existing use cases ├── n8n-workflow-builder.md # Craftsperson — builds workflow JSON └── use-case-tester.md # QA — deploy-trigger-fix loops ``` ## Bundled documentation catalog The `discover-codika-guides` skill ships with the complete platform documentation. Agents read these guides at runtime to ensure they follow current patterns. ### Core guides | Guide | What it covers | | ----------------------------- | --------------------------------------------------------------------------------------------- | | `use-case-guide.md` | Overall architecture, mandatory patterns, placeholder system, trigger types, config structure | | `specific/config-patterns.md` | config.ts structure, exports, workflow array, integration UIDs, display metadata | | `specific/codika-nodes.md` | Codika Init, Submit Result, Report Error, Upload File node configuration | ### Trigger-specific guides | Guide | What it covers | | ---------------------------------- | ----------------------------------------------------------------------- | | `specific/http-triggers.md` | HTTP webhook and form trigger patterns | | `specific/schedule-triggers.md` | Cron/scheduled trigger patterns | | `specific/third-party-triggers.md` | Gmail, Slack, WhatsApp, Pipedrive, Calendly service event triggers | | `specific/sub-workflows.md` | Reusable workflow logic, Execute Workflow pattern, SUBWKFL placeholders | ### Specialized guides | Guide | What it covers | | ---------------------------------- | -------------------------------------------------------------------------- | | `specific/ai-nodes.md` | chainLlm vs agent nodes, LangChain wiring, model configuration, \$fromAI() | | `specific/placeholder-patterns.md` | Complete reference for all 11 placeholder types with suffix patterns | | `specific/process-input-schema.md` | Deployment parameters (INSTPARM), field types, context-aware serialization | | `specific/data-ingestion.md` | RAG/document embedding pipeline configuration | | `specific/agent-skills.md` | Creating SKILL.md files for agent discoverability | ### Integration guides (19) | Category | Integrations | | --------------------------- | ----------------------------------------------------------------------------------------------- | | **AI providers** (FLEXCRED) | Anthropic, OpenAI, Tavily, xAI, OpenRouter, Mistral, Cohere, DeepSeek, Fal AI | | **Organization** (ORGCRED) | WhatsApp, Slack, Twilio, Folk CRM, Pipedrive | | **User** (USERCRED) | Google (Gmail, Sheets, Drive, Calendar), Microsoft (Teams, Outlook, OneDrive), Calendly, Notion | | **Instance** (INSTCRED) | Supabase | ### Additional resources | Resource | What it covers | | -------------------------------- | ---------------------------------------------------------------------- | | `plan-examples/` | Example build plans showing how the builder agent designs architecture | | `post-creation/common-errors.md` | Common issues after creating workflows and how to fix them | | `use-case/whatsapp-bots.md` | WhatsApp bot-specific patterns and conventions | ## Agent-to-skill dependency map Each agent uses a specific set of skills from the same `codika` plugin (all skills and agents are colocated): | Agent | Skills used | | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | **codika:use-case-builder** | `codika:init-use-case`, `codika:verify-use-case` | | **codika:use-case-modifier** | `codika:verify-use-case` | | **codika:n8n-workflow-builder** | *(none — outputs JSON directly)* | | **codika:use-case-tester** | `codika:deploy-use-case`, `codika:trigger-workflow`, `codika:list-executions`, `codika:get-execution`, `codika:verify-use-case` | All agents read platform documentation via `codika:discover-codika-guides` before starting work. ## Troubleshooting ### Authentication errors If agents fail with "API key is required" or authentication errors, run: ```bash theme={null} codika login codika whoami # verify you're authenticated ``` ### Missing codika plugin The builder agents depend on the `codika` plugin for CLI operations. If deployment or verification skills fail, ensure both plugins are installed. ### Guide not found If an agent can't find documentation, verify the `discover-codika-guides` skill is available. The skill locates guides using glob patterns against its bundled `references/` directory. ### Validation failures after building If `codika verify use-case` fails after the builder creates a use case: 1. Read the specific error messages — they usually point to the exact issue 2. Use `codika verify use-case --fix` to auto-fix common violations 3. For persistent issues, invoke `use-case-modifier` with the error details ### Tester stuck in loop If `use-case-tester` hits its 5-iteration limit: * Check the escalation report for what was tried * Common root causes: missing OAuth credentials on the platform, external API rate limits, or integration-specific configuration issues that the agent can't resolve * Verify integrations are configured: `codika integration list` # Usage Patterns Source: https://doc.codika.io/builder/workflows Common workflows for using the Builder System — from creating use cases to testing and iterating ## Creating a use case from scratch The most common workflow: describe a business goal, get a production-ready use case. **Your prompt:** ``` I need an automation that monitors our Gmail inbox for emails from clients, extracts key information using AI, and logs everything in a Google Sheet. If the email contains an attachment, save it to Google Drive. ``` **What happens:** 1. The `use-case-builder` agent reads the platform documentation 2. It designs an architecture with the right triggers, workflows, and integrations 3. It presents a plan: "I'll create 2 workflows — a Gmail service-event trigger for new emails, and a sub-workflow for AI extraction and file handling" 4. After your approval, it creates the folder structure and delegates each workflow to `n8n-workflow-builder` 5. It validates everything and shows you the complete use case **Tips for good prompts:** * Describe the **business goal**, not the implementation ("monitor Gmail" not "use a Gmail trigger node") * Mention the integrations you need (Gmail, Sheets, Drive, Slack, etc.) * Specify what should happen on success and on failure * Include any user-configurable settings ("the user should be able to choose which email label to monitor") ## Modifying an existing use case When you need to add features, change triggers, or refactor. **Your prompt:** ``` Add a Slack notification to the invoice-processor use case. When an invoice is successfully processed, post a summary to a Slack channel. ``` **What happens:** 1. The `use-case-modifier` reads the entire existing use case 2. It identifies that a new workflow is needed (Slack notification) and that the main workflow needs to call it 3. It presents a change plan: "I'll add a new sub-workflow for Slack posting, update the main workflow's success branch to call it, and add the Slack ORGCRED integration to config.ts" 4. After approval, it makes targeted edits and delegates the new workflow to `n8n-workflow-builder` 5. It validates to ensure nothing was broken ## Building a single workflow For when you need one workflow, not a full use case. **Your prompt:** ``` Build an HTTP-triggered workflow that accepts a company name, searches for it using Tavily, and returns a structured summary. ``` **What happens:** 1. The `n8n-workflow-builder` reads the HTTP trigger guide and integration guides 2. It creates a complete workflow JSON with the correct trigger, Codika Init, business logic, and Submit Result/Report Error pattern 3. It handles all placeholder usage, credential configuration, and node positioning ## Testing and debugging After building (or when something breaks), use the tester. **Your prompt:** ``` Test the invoice-processor use case and fix any issues. ``` **What happens:** 1. The `use-case-tester` verifies and deploys the use case 2. It triggers each HTTP workflow with test data constructed from `inputSchema` 3. On success, it verifies outputs match `outputSchema` 4. On failure, it fetches the execution trace, diagnoses the error, fixes the workflow, and deploys again 5. It repeats up to 5 times until all workflows pass ## The full build-test cycle For maximum confidence, chain the agents together: ``` Step 1: use-case-builder creates the use case Step 2: use-case-tester deploys and tests it Step 3: use-case-modifier fixes any remaining issues Step 4: use-case-tester re-tests ``` You can do this in a single conversation: ``` "Create a use case that [business goal], then test it end-to-end and fix any issues." ``` ## Writing effective prompts ### Do * **Be specific about integrations:** "Use Gmail for email, Google Sheets for logging, and Slack for notifications" * **Describe the data flow:** "Extract the sender, subject, and key dates from each email" * **Mention edge cases:** "If the AI can't parse the email, log it as unprocessed and skip" * **Specify user settings:** "The user should configure their Slack channel and email filter criteria at install time" ### Don't * **Don't specify implementation details:** "Use a FLEXCRED\_ANTHROPIC placeholder" — the agent knows this * **Don't prescribe trigger types:** "Make it an HTTP POST webhook" — let the agent decide the best trigger * **Don't worry about Codika patterns:** Init nodes, Submit Result, Report Error — the agent handles these automatically * **Don't specify node positioning or IDs:** The agent follows standard conventions # Agent Skills Source: https://doc.codika.io/concepts/agent-skills Make your workflows discoverable and usable by AI agents — skills describe what each endpoint does, how to call it, and what to expect back ## What are agent skills? Agent skills are documentation files that describe how to interact with your deployed workflows. Each skill is a directory containing a `SKILL.md` file that follows the [Claude Agent Skills format](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview). When you deploy a use case with skills, agents can download them via `codika get skills` and immediately understand how to trigger your workflows — input schemas, output schemas, example payloads, and all. **Automate this.** The [Builder System](/builder/overview) agents can create complete use cases with properly configured agent skills — no manual SKILL.md writing needed. ## Why skills matter Without skills, an agent has no way to know what endpoints your use case exposes or how to use them. Skills bridge the gap between **deployed workflows** and **agent consumption**. ``` You build workflows → Codika deploys as HTTP endpoints → Skills explain how to use them → Agents discover and call them ``` **Credential decoupling:** You connect integrations to the platform once. When an agent triggers a workflow, Codika injects the right credentials at runtime. The agent only holds a Codika API key — it calls actions, not raw APIs. You control the agent's tool stack by choosing which workflows get skills. ## How agents use skills Skills are documentation — they explain what's available. The actual execution always goes through the Codika platform: ``` Agent reads SKILL.md → understands input/output Agent calls: codika trigger --payload-file input.json → Codika CLI sends request with API key → triggerWebhookPublic cloud function validates key → Platform resolves integration credentials (OAuth, API keys) → n8n workflow executes with real credentials injected → Result returned to agent ``` ### What agents need | Requirement | Why | How | | ---------------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `codika` CLI installed | To trigger workflows and fetch skills | `npm install -g codika` | | Codika API key | Authentication for all platform calls | `codika login` or `CODIKA_API_KEY` env var. Use `--profile ` on any command to target a specific profile without switching the global active one. Discover profiles and their org IDs via `codika use --json`. | | Process instance ID | Identifies which deployed use case to interact with | From `project.json` or provided explicitly | ### What the agent never touches All integration credentials (OAuth tokens, API keys, database passwords) are managed by the platform and injected into workflows at runtime via the [placeholder system](/concepts/placeholders). The Codika API key only grants permission to trigger workflows and read skills — it cannot access the underlying integration credentials. This is the core of Codika's credential decoupling: **agents get actions, not keys**. ## Which workflows get skills? | Workflow type | Gets a skill? | Why | | ----------------------------------- | ------------- | --------------------------------------------------- | | HTTP-triggered | **Yes** | User/agent-facing endpoint with input/output | | Scheduled (with manual trigger URL) | **Yes** | Auto-runs but can be manually triggered for testing | | Sub-workflow | No | Internal helper, called by other workflows | | Data ingestion | No | Internal, triggered by document uploads | | Service event (webhook receiver) | Usually no | Triggered by external services, not by agents | ## Folder structure Skills live in a `skills/` folder alongside `workflows/`: ``` my-use-case/ ├── config.ts ├── workflows/ │ ├── main-workflow.json │ ├── scheduled-report.json │ └── text-processor.json # sub-workflow — no skill └── skills/ ├── main-workflow/ # one directory per skill │ └── SKILL.md └── scheduled-report/ └── SKILL.md ``` Each skill is a **directory** containing a `SKILL.md` file. This matches Claude's expected format — downloaded skills can be placed directly in `.claude/skills/` for Claude Code auto-discovery or uploaded to the Claude API. ## SKILL.md format ### Frontmatter (required) ```yaml theme={null} --- name: my-use-case-process-text description: Submits text for AI processing via the main-workflow HTTP endpoint. Returns processed text with a timestamp. workflowTemplateId: main-workflow --- ``` | Field | Required | Constraints | | -------------------- | -------- | ---------------------------------------------------------------------------------------- | | `name` | Yes | Max 64 chars, lowercase letters/numbers/hyphens only, no "anthropic" or "claude" | | `description` | Yes | Max 1024 chars, non-empty, **third person** ("Submits text for..." not "Use this to...") | | `workflowTemplateId` | Yes | Must match a `workflowTemplateId` from the workflows array in `config.ts` | ### Body The body should be concise (under 500 lines) and include: 1. **Title** — H1 with the workflow name 2. **One-line overview** — What the endpoint does, which integrations it uses 3. **How to trigger** — Exact `codika trigger` command with example payload 4. **Input** — Table of input parameters 5. **Output** — Example JSON response 6. **Notes** — Cost, limitations, edge cases ## HTTP workflow skill example ```markdown theme={null} --- name: wat-direct-messaging description: Sends a WhatsApp message to a list of phone numbers via Twilio. Accepts up to 500 recipients and returns delivery statistics. workflowTemplateId: http-direct-messaging --- # Direct Messaging Sends a WhatsApp message to up to 500 phone numbers via Twilio. ## How to trigger \`\`\`bash codika trigger http-direct-messaging --payload-file - <<'EOF' { "phone_numbers": ["32477123456", "33612345678"], "message_content": "Hello from WAT community!" } EOF \`\`\` ## Input | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | phone_numbers | array of strings | yes | Phone numbers (8-15 digits, no + prefix). Max 500. | | message_content | text | yes | Message body. Max 4096 characters. | ## Output \`\`\`json { "success": true, "total_sent": 2, "total_failed": 0, "sent_at": "2025-03-15T10:30:00.000Z" } \`\`\` ## Notes - Cost: 1 credit per execution - Uses: Twilio (WhatsApp), Supabase (audit logging) ``` ## Scheduled workflow skill example ```markdown theme={null} --- name: wat-event-weekly-digest description: Sends a personalized weekly digest of upcoming events to community members every Monday at 9 AM. Can be manually triggered for testing. workflowTemplateId: scheduled-event-weekly-digest --- # Event Weekly Digest Runs automatically every Monday at 9:00 AM (Europe/Brussels). ## Manual trigger (for testing) \`\`\`bash codika trigger scheduled-event-weekly-digest \`\`\` No payload required. ## Notes - Cost: 1 credit per execution - Uses: Supabase (event data), Twilio (WhatsApp delivery) ``` ## Deployment lifecycle ### 1. Create skills alongside workflows ```bash theme={null} codika init ./my-use-case --name "My Use Case" # Creates skills/main-workflow/SKILL.md and skills/scheduled-report/SKILL.md ``` ### 2. Validate ```bash theme={null} codika verify use-case ./my-use-case ``` The verifier checks: * Every subdirectory in `skills/` contains a `SKILL.md` file * Frontmatter has valid `name`, `description`, and `workflowTemplateId` * `name` follows Claude naming rules (lowercase, hyphens, max 64 chars) * `workflowTemplateId` matches an existing workflow ### 3. Deploy ```bash theme={null} codika deploy use-case ./my-use-case ``` Skills are automatically collected from `skills/*/SKILL.md` and sent with the deployment. No changes to `config.ts` needed. ### 4. Download skills (agents) ```bash theme={null} # From inside a use case folder codika get skills # With explicit process instance ID codika get skills # Save directly to Claude Code skills directory codika get skills --output .claude/skills # JSON output for programmatic use codika get skills --json ``` Downloaded skills are written as proper Claude-compatible directories: ``` ./skills/ ├── my-use-case-process-text/ │ └── SKILL.md └── my-use-case-scheduled-report/ └── SKILL.md ``` ## Installing skills for agents ### Claude Code (one command) Download skills directly into Claude Code's auto-discovery directory: ```bash theme={null} codika get skills --output .claude/skills ``` That's it. Claude Code reads `.claude/skills/` at startup. Each skill's `name` and `description` are loaded into the system prompt (\~100 tokens each). When a user request matches a skill's description, Claude reads the full `SKILL.md` body and follows the instructions. **Where `.claude/skills/` lives:** * **Project-level** (recommended): `.claude/skills/` in your project root — skills are available in that project * **Personal**: `~/.claude/skills/` — skills are available in all your projects **What happens after installation:** ``` User: "Send a WhatsApp message to these phone numbers" → Claude sees skill description: "Sends a WhatsApp message to a list of phone numbers via Twilio" → Claude reads skills/wat-direct-messaging/SKILL.md → Claude generates: codika trigger http-direct-messaging --payload-file ... → Workflow executes via Codika platform (credentials injected at runtime) → Result returned to user ``` ### Claude API Upload skills programmatically for use in API-based agents: ```python theme={null} from anthropic.lib import files_from_dir # First download locally # codika get skills --output ./skills # Then upload to the Claude API skill = client.beta.skills.create( display_title="Direct Messaging", files=files_from_dir("./skills/wat-direct-messaging"), betas=["skills-2025-10-02"], ) # Use in a message response = client.beta.messages.create( model="claude-sonnet-4-6", max_tokens=4096, betas=["code-execution-2025-08-25", "skills-2025-10-02"], container={ "skills": [{"type": "custom", "skill_id": skill.id, "version": "latest"}] }, messages=[{"role": "user", "content": "Send a welcome message to +32477123456"}], tools=[{"type": "code_execution_20250825", "name": "code_execution"}], ) ``` ### Claude Agent SDK Place skills in `.claude/skills/` and include `"Skill"` in your `allowed_tools`: ```typescript theme={null} import { Agent } from '@anthropic-ai/agent-sdk'; const agent = new Agent({ model: 'claude-sonnet-4-6', allowed_tools: ['Skill', 'Bash'], }); ``` The SDK auto-discovers skills from `.claude/skills/` when it runs. ### Triggering from a skill After reading a skill, the agent generates the appropriate CLI command: ```bash theme={null} codika trigger --payload-file input.json --poll ``` All calls go through the Codika platform — credentials are resolved at runtime. ## Best practices * **One skill per triggerable workflow** — don't combine multiple endpoints into one skill * **Be concise** — under 500 lines. Claude is smart; only explain what it can't infer * **Show exact payloads** — include real `codika trigger` commands with copy-pasteable JSON * **Third-person descriptions** — "Sends a message..." not "Use this to send..." * **Prefix names with use case slug** — `wat-direct-messaging`, `propale-generate-proposal` * **Mention integrations and cost** — helps agents understand dependencies and expense * **For scheduled workflows** — always explain the automatic schedule AND the manual trigger # Credentials Source: https://doc.codika.io/concepts/credentials How Codika manages credential isolation across users — FLEXCRED, USERCRED, ORGCRED, and other credential placeholder types ## Overview Credentials in Codika workflows are never hardcoded. Instead, workflows use placeholder tokens that get replaced at deployment time with real credential IDs from n8n. This ensures every user gets their own isolated credentials. There are six credential placeholder types, each serving a different scope: | Type | Scope | Who provides | Fallback | | ----------- | ---------------------- | --------------------- | --------------------- | | `FLEXCRED` | AI providers | Organization → Codika | Codika's shared keys | | `USERCRED` | Per-user integrations | User (OAuth) | None (required) | | `ORGCRED` | Org-wide integrations | Organization admin | None (required) | | `INSTCRED` | Per-instance databases | User (at install) | None (required) | | `SYSCREDS` | System-level | Codika platform | None (system-managed) | | `ORGSECRET` | Org configuration | Organization settings | None (required) | ## FLEXCRED — Flexible AI credentials The most common credential type for AI-powered workflows. Uses the organization's own API key if available, otherwise falls back to Codika's shared pool (billed via credits). ```json theme={null} "credentials": { "anthropicApi": { "id": "{{FLEXCRED_ANTHROPIC_ID_DERCXELF}}", "name": "{{FLEXCRED_ANTHROPIC_NAME_DERCXELF}}" } } ``` **Supported providers:** Anthropic, OpenAI, Tavily, Google Gemini, X AI, Open Router, Mistral, Cohere, Deep Seek The platform automatically decides which key to use based on whether your organization has configured its own API key for that provider. ## USERCRED — User integration credentials OAuth tokens from the user's connected integrations. Each user connects their own accounts (Gmail, Drive, Sheets, etc.) via the Codika dashboard. ```json theme={null} "credentials": { "gmailOAuth2": { "id": "{{USERCRED_GOOGLE_GMAIL_ID_DERCRESU}}", "name": "{{USERCRED_GOOGLE_GMAIL_NAME_DERCRESU}}" } } ``` **Available integrations:** Google Gmail, Google Drive, Google Sheets, Google Calendar, Microsoft (Teams/Outlook), Calendly, Notion These are required — if a user hasn't connected the integration, the workflow cannot be deployed for them. ## ORGCRED — Organization-level credentials Shared credentials managed by organization admins. Used for services where the entire org shares one account (e.g., company Slack workspace, CRM). ```json theme={null} "credentials": { "slackOAuth2Api": { "id": "{{ORGCRED_SLACK_ID_DERCGRO}}", "name": "{{ORGCRED_SLACK_NAME_DERCGRO}}" } } ``` **Common integrations:** Slack, WhatsApp, Pipedrive, Folk CRM ## INSTCRED — Instance-level credentials Per-deployment credentials configured during process installation. Used for database connections or external services that differ per deployment. ```json theme={null} "credentials": { "supabaseApi": { "id": "{{INSTCRED_SUPABASE_ID_DERCTSNI}}", "name": "{{INSTCRED_SUPABASE_NAME_DERCTSNI}}" } } ``` ## How credentials appear in workflow JSON Credentials are always specified on the n8n node that uses them — never on chain/agent wrapper nodes. For LLM workflows, credentials go on the **model node**, not the chain node: ```json theme={null} { "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic", "typeVersion": 1.3, "parameters": { "model": { "__rl": true, "value": "claude-haiku-4-5-20251001", "mode": "list" }, "options": { "maxTokensToSample": 1024, "temperature": 0.3 } }, "credentials": { "anthropicApi": { "id": "{{FLEXCRED_ANTHROPIC_ID_DERCXELF}}", "name": "{{FLEXCRED_ANTHROPIC_NAME_DERCXELF}}" } } } ``` ## Integration UIDs When listing required integrations in `config.ts`, use these standard UIDs: | UID | Service | | ----------------- | ------------------------------------ | | `anthropic` | Anthropic (Claude) | | `openai` | OpenAI | | `tavily` | Tavily Web Search | | `google_gmail` | Google Gmail | | `google_drive` | Google Drive | | `google_sheets` | Google Sheets | | `google_calendar` | Google Calendar | | `slack` | Slack | | `folk` | Folk CRM | | `pipedrive` | Pipedrive | | `calendly` | Calendly | | `notion` | Notion | | `microsoft` | Microsoft (Teams, Outlook, OneDrive) | ```typescript theme={null} { workflowTemplateId: 'my-workflow', integrationUids: ['anthropic', 'google_gmail', 'slack'], // ... } ``` ## Validation The CLI validates credential patterns via the `CK-CREDENTIALS` rule: ```bash theme={null} codika verify use-case ./my-use-case ``` Common issues: * Using raw credential IDs instead of placeholders * Wrong suffix for the credential type * Credentials on the wrong node (e.g., on `chainLlm` instead of `lmChatAnthropic`) # Placeholders Source: https://doc.codika.io/concepts/placeholders The 11 placeholder types that make workflows portable — template tokens replaced at deployment with real values ## How placeholders work Workflows contain template tokens like `{{FLEXCRED_ANTHROPIC_ID_DERCXELF}}` that get replaced at deployment time with real values. This is how Codika makes a single workflow definition work for multiple users, each with their own credentials and configuration. **Pattern:** `{{TYPE_KEY_SUFFIX}}` * **TYPE**: The placeholder category (e.g., `FLEXCRED`, `USERDATA`) * **KEY**: The specific value being referenced (e.g., `ANTHROPIC_ID`, `PROCESS_INSTANCE_UID`) * **SUFFIX**: The type name reversed (e.g., `FLEXCRED` → `DERCXELF`) The reversed suffix ensures placeholder patterns are unique and cannot collide with real data. ## Complete reference ### PROCDATA — Process-level values **Suffix:** `_ATADCORP` | **Replaced at:** First deployment Values derived from the process (project) itself. Same for all users. | Placeholder | Value | | ---------------------------------- | ---------------------- | | `{{PROCDATA_PROCESS_ID_ATADCORP}}` | The process/project ID | | `{{PROCDATA_NAMESPACE_ATADCORP}}` | Process namespace | **Common usage:** Webhook paths, API URLs ```json theme={null} "path": "{{PROCDATA_PROCESS_ID_ATADCORP}}/{{USERDATA_PROCESS_INSTANCE_UID_ATADRESU}}/analyze" ``` ### USERDATA — Per-user runtime values **Suffix:** `_ATADRESU` | **Replaced at:** Instance deployment Values specific to each user's installation. | Placeholder | Value | | -------------------------------------------- | -------------------------- | | `{{USERDATA_PROCESS_INSTANCE_UID_ATADRESU}}` | User's process instance ID | | `{{USERDATA_USER_ID_ATADRESU}}` | User's unique ID | | `{{USERDATA_ORGANIZATION_ID_ATADRESU}}` | User's organization ID | **Common usage:** Webhook IDs, Codika Init parameters ```json theme={null} "webhookId": "{{USERDATA_PROCESS_INSTANCE_UID_ATADRESU}}" ``` ### MEMSECRT — Member-level secrets **Suffix:** `_TRCESMEM` | **Replaced at:** Instance deployment Per-user secrets for platform API authentication. | Placeholder | Value | | -------------------------------------- | ------------------------------ | | `{{MEMSECRT_EXECUTION_AUTH_TRCESMEM}}` | Execution authentication token | **Common usage:** Codika Init node for schedule/service event triggers ```json theme={null} "memberSecret": "{{MEMSECRT_EXECUTION_AUTH_TRCESMEM}}" ``` ### FLEXCRED — Flexible AI credentials **Suffix:** `_DERCXELF` | **Replaced at:** Deployment AI provider credentials with fallback logic: uses the organization's own API key if configured, otherwise falls back to Codika's shared keys (pay-per-use credits). | Provider | ID placeholder | Name placeholder | | ------------- | ---------------------------------------- | ------------------------------------------ | | Anthropic | `{{FLEXCRED_ANTHROPIC_ID_DERCXELF}}` | `{{FLEXCRED_ANTHROPIC_NAME_DERCXELF}}` | | OpenAI | `{{FLEXCRED_OPENAI_ID_DERCXELF}}` | `{{FLEXCRED_OPENAI_NAME_DERCXELF}}` | | Tavily | `{{FLEXCRED_TAVILY_ID_DERCXELF}}` | `{{FLEXCRED_TAVILY_NAME_DERCXELF}}` | | Google Gemini | `{{FLEXCRED_GOOGLE_GEMINI_ID_DERCXELF}}` | `{{FLEXCRED_GOOGLE_GEMINI_NAME_DERCXELF}}` | | X AI | `{{FLEXCRED_X_AI_ID_DERCXELF}}` | `{{FLEXCRED_X_AI_NAME_DERCXELF}}` | | Open Router | `{{FLEXCRED_OPEN_ROUTER_ID_DERCXELF}}` | `{{FLEXCRED_OPEN_ROUTER_NAME_DERCXELF}}` | | Mistral | `{{FLEXCRED_MISTRAL_ID_DERCXELF}}` | `{{FLEXCRED_MISTRAL_NAME_DERCXELF}}` | | Cohere | `{{FLEXCRED_COHERE_ID_DERCXELF}}` | `{{FLEXCRED_COHERE_NAME_DERCXELF}}` | | Deep Seek | `{{FLEXCRED_DEEP_SEEK_ID_DERCXELF}}` | `{{FLEXCRED_DEEP_SEEK_NAME_DERCXELF}}` | **Common usage:** LLM model credentials ```json theme={null} "credentials": { "anthropicApi": { "id": "{{FLEXCRED_ANTHROPIC_ID_DERCXELF}}", "name": "{{FLEXCRED_ANTHROPIC_NAME_DERCXELF}}" } } ``` ### USERCRED — User integration credentials **Suffix:** `_DERCRESU` | **Replaced at:** Instance deployment OAuth tokens from the user's connected integrations. | Integration | ID placeholder | Name placeholder | | -------------------------- | ------------------------------------------ | -------------------------------------------- | | Gmail | `{{USERCRED_GOOGLE_GMAIL_ID_DERCRESU}}` | `{{USERCRED_GOOGLE_GMAIL_NAME_DERCRESU}}` | | Google Sheets | `{{USERCRED_GOOGLE_SHEETS_ID_DERCRESU}}` | `{{USERCRED_GOOGLE_SHEETS_NAME_DERCRESU}}` | | Google Drive | `{{USERCRED_GOOGLE_DRIVE_ID_DERCRESU}}` | `{{USERCRED_GOOGLE_DRIVE_NAME_DERCRESU}}` | | Google Calendar | `{{USERCRED_GOOGLE_CALENDAR_ID_DERCRESU}}` | `{{USERCRED_GOOGLE_CALENDAR_NAME_DERCRESU}}` | | Microsoft (Teams, Outlook) | `{{USERCRED_MICROSOFT_ID_DERCRESU}}` | `{{USERCRED_MICROSOFT_NAME_DERCRESU}}` | | Calendly | `{{USERCRED_CALENDLY_ID_DERCRESU}}` | `{{USERCRED_CALENDLY_NAME_DERCRESU}}` | | Notion | `{{USERCRED_NOTION_ID_DERCRESU}}` | `{{USERCRED_NOTION_NAME_DERCRESU}}` | **Common usage:** n8n node credentials ```json theme={null} "credentials": { "gmailOAuth2": { "id": "{{USERCRED_GOOGLE_GMAIL_ID_DERCRESU}}", "name": "{{USERCRED_GOOGLE_GMAIL_NAME_DERCRESU}}" } } ``` ### ORGCRED — Organization-level credentials **Suffix:** `_DERCGRO` | **Replaced at:** Deployment Credentials shared across the entire organization (e.g., a shared Slack workspace token). | Integration | ID placeholder | Name placeholder | | ----------- | ---------------------------------- | ------------------------------------ | | Slack | `{{ORGCRED_SLACK_ID_DERCGRO}}` | `{{ORGCRED_SLACK_NAME_DERCGRO}}` | | WhatsApp | `{{ORGCRED_WHATSAPP_ID_DERCGRO}}` | `{{ORGCRED_WHATSAPP_NAME_DERCGRO}}` | | Pipedrive | `{{ORGCRED_PIPEDRIVE_ID_DERCGRO}}` | `{{ORGCRED_PIPEDRIVE_NAME_DERCGRO}}` | | Folk CRM | `{{ORGCRED_FOLK_ID_DERCGRO}}` | `{{ORGCRED_FOLK_NAME_DERCGRO}}` | ### ORGSECRET — Organization secrets **Suffix:** `_TERCESORG` | **Replaced at:** Deployment Configuration values stored at the organization level. | Placeholder | Value | | ------------------------------------------- | ---------------------------------- | | `{{ORGSECRET_N8N_BASE_URL_TERCESORG}}` | Organization's n8n instance URL | | `{{ORGSECRET_ERROR_WORKFLOW_ID_TERCESORG}}` | Platform error handler workflow ID | **Common usage:** Workflow settings, webhook URLs ```json theme={null} "settings": { "errorWorkflow": "{{ORGSECRET_ERROR_WORKFLOW_ID_TERCESORG}}" } ``` ### SYSCREDS — System-level credentials **Suffix:** `_SDERCSYS` | **Replaced at:** Deployment Platform-level system credentials managed by Codika. | Placeholder | Value | | ------------------------------------ | ------------------------ | | `{{SYSCREDS_ANTHROPIC_ID_SDERCSYS}}` | System Anthropic API key | ### INSTPARM — Deployment parameters **Suffix:** `_MRAPTSNI` | **Replaced at:** Instance deployment User-configured values set during process installation. Defined in `getDeploymentInputSchema()`. ```json theme={null} // In Code nodes — no extra quotes needed, context-aware serialization const companyName = {{INSTPARM_COMPANY_NAME_MRAPTSNI}}; // String → "Acme Corp" const maxItems = {{INSTPARM_MAX_ITEMS_MRAPTSNI}}; // Number → 50 const enableFeature = {{INSTPARM_ENABLE_FEATURE_MRAPTSNI}}; // Boolean → true const domains = {{INSTPARM_ALLOWED_DOMAINS_MRAPTSNI}}; // Array → ["a.com","b.com"] ``` See [Deployment Parameters](/guides/deployment-parameters) for full usage guide. ### INSTCRED — Instance-level credentials **Suffix:** `_DERCTSNI` | **Replaced at:** Instance deployment Per-deployment database connections or service credentials. | Placeholder | Value | | ------------------------------------- | --------------------- | | `{{INSTCRED_SUPABASE_ID_DERCTSNI}}` | Supabase connection | | `{{INSTCRED_POSTGRESQL_ID_DERCTSNI}}` | PostgreSQL connection | ### SUBWKFL — Sub-workflow references **Suffix:** `_LFKWBUS` | **Replaced at:** Deployment Resolved n8n workflow IDs for sub-workflows. The key is the sub-workflow's `workflowTemplateId`. ```json theme={null} // In Execute Workflow node "workflowId": { "__rl": true, "mode": "id", "value": "{{SUBWKFL_text-processor_LFKWBUS}}" } ``` See [Sub-Workflows](/guides/sub-workflows) for the full pattern. ## Replacement timeline | When | Placeholder types replaced | | --------------------------------------- | ---------------------------------------------------------------------------- | | **First deployment** (process creation) | PROCDATA, ORGSECRET, SYSCREDS | | **Instance deployment** (per-user) | USERDATA, MEMSECRT, USERCRED, ORGCRED, FLEXCRED, INSTPARM, INSTCRED, SUBWKFL | ## Validation The CLI validates placeholder syntax via the `CK-PLACEHOLDERS` rule: ```bash theme={null} codika verify use-case ./my-use-case ``` Common issues: * Wrong suffix (e.g., using `_DERCXELF` for a `USERCRED` placeholder) * Typo in type name * Missing closing `}}` # Processes Source: https://doc.codika.io/concepts/processes The lifecycle of a deployed automation — from use case folder to live process with versioning, environments, and user isolation ## What is a process? When you deploy a use case, the platform creates a **process** — the public, discoverable representation of your automation. Users can find, install, and run processes with their own credentials. Each process has three layers: ``` Process (public listing) └── Deployment template (immutable version snapshot) Process instance (user installation) └── Deployment instance (running copy with real workflow IDs) ``` ## Process The top-level entity. Represents your automation on the platform. | Property | Description | | ------------ | ----------------------------------------------------------- | | Title | Display name | | Description | What the automation does | | Visibility | Who can see and install it | | Tags | Categorization (e.g., `email`, `ai`, `crm`) | | Process type | `personal` (one per user) or `organizational` (one per org) | ### Visibility levels | Level | Who can see and install | | ---------------- | ------------------------------- | | `private` | Only the owner | | `userList` | Specific users | | `teamList` | Specific teams | | `organizational` | All members of the organization | | `public` | Anyone on the platform | ## Deployment template An immutable snapshot of a specific version. When you deploy version 1.2, the platform stores a template containing all workflow data with placeholders still present (not yet replaced with real values). Templates are **never modified** after creation. A new deployment always creates a new template. | Property | Description | | --------- | --------------------------------------------------- | | Version | API version (e.g., `1.0`, `1.1`, `2.0`) | | Status | `inactive` → `published` → `deprecated` | | Workflows | Workflow metadata (triggers, schemas, integrations) | ## Process instance A user's personal installation of a process. Each user gets their own instance with isolated state and credentials. | Property | Description | | --------------------- | --------------------------------------------------- | | Environment | `dev` or `prod` | | Version | Which template version this instance runs | | Active | Whether workflows are enabled | | Sharing | Who in the org can use this instance | | Deployment parameters | User-configured values (from INSTPARM placeholders) | ### Instance states | State | Behavior | | ------------------- | --------------------------------------------------------------- | | Active | Fully functional, workflows execute on triggers | | User paused | Visible but workflows disabled (user chose to pause) | | Deploy failed | Visible but needs retry (deployment error occurred) | | Missing integration | Visible but needs reconnection (OAuth token expired or deleted) | | Archived | Hidden and disabled (soft-deleted) | ### Dev/Prod environments Process owners get automatic environment management: * **First deploy:** Creates a `dev` instance, activates it * **Publish to prod:** Use `codika publish ` to promote a deployment. Auto-creates a `prod` instance. * **Redeploy to dev:** Updates the `dev` instance with new workflows By default, both dev and prod instances run simultaneously after publishing. Use `--auto-toggle-dev-prod` with the publish command to pause dev when prod is active. Use `codika list executions ` to view recent executions for either environment — pass the dev or prod instance ID. ### Rerunning a deployment without versioning Sometimes you need to change deployment parameters (e.g., company name, language, timezone) without creating a new template version. The `codika rerun deployment` command handles this: * **Parameters are merged** — you only pass what changed; existing parameters keep their values * **No new template** — the instance continues running the same template version * **Uses owner credentials** — workflows are redeployed with the instance owner's integration bindings * **Retry failed deployments** — failed instances can be retried without `--force` This is useful after publishing to production when you need to adjust configuration, or when a deployment fails and you want to retry with the same or updated parameters. ```bash theme={null} # Change a parameter on the dev instance codika rerun deployment --param LANGUAGE=fr # Retry a failed deployment codika rerun deployment --environment dev # Update prod parameters codika rerun deployment --environment prod --param COMPANY_NAME="New Corp" --force ``` See the [`codika rerun deployment` reference](/operations/rerun-deployment) for full details. ## Deployment instance The running copy of a process instance with real n8n workflow IDs. This is what connects your process instance to live workflows in n8n. | Property | Description | | ----------------- | ------------------------------------------------------------------ | | Status | `pending` → `deploying` → `deployed` or `failed` | | Workflow mappings | Links between your workflow template IDs and live n8n workflow IDs | ### Deployment status flow ``` pending → deploying → deployed (success) → failed (error) deployed → updating → deployed (version update success) → failed (version update error) ``` ## Deployment pipeline When you run `codika deploy use-case`, the platform: 1. **Validates** the request (authentication, format, required fields) 2. **Calculates version** based on your version strategy (patch/minor/major) 3. **Creates a deployment template** — an immutable version snapshot 4. **Creates or updates** the process, process instance, and deployment instance 5. **Deploys to n8n** — for each workflow: * Replaces all placeholders with real values (credentials, parameters, IDs) * Creates or updates the workflow in n8n 6. **Returns** the deployment result (IDs, version, status) ## Version updates When a new version is published: * **Pinned instances**: Users are notified that an update is available and can choose when to apply it * **Unpinned instances**: Automatically updated to the new version — the platform creates a new deployment instance and updates the live workflows If an automatic update fails, the instance falls back to showing "update available" for manual retry. ## Public API access Process instances with HTTP triggers expose a public API for triggering workflows and checking execution status. Authentication uses a per-instance API key passed via the `X-API-Key` header. The `codika trigger` and `codika get execution` commands wrap these endpoints — you don't need to call them directly. # Input & Output Schemas Source: https://doc.codika.io/concepts/schemas How to define form inputs for workflow triggers and structured output fields for execution results ## Overview Schemas define the data contract between users and workflows: * **Input schemas** define what the user fills in before triggering a workflow (forms) * **Output schemas** define what the workflow returns after execution (results) Both are defined in `config.ts` as part of the workflow configuration. ## Input schemas Input schemas are used by **HTTP triggers** and **sub-workflow triggers** to define what data the workflow expects. ### Structure An input schema is an array of sections, each containing an array of fields: ```typescript theme={null} function getInputSchema(): FormInputSchema { return [ { type: 'section', title: 'Configuration', collapsible: false, inputSchema: [ { key: 'query', type: 'text', label: 'Search Query', description: 'What to search for', placeholder: 'Enter your query...', required: true, maxLength: 1000, }, ], }, { type: 'section', title: 'Advanced Options', collapsible: true, inputSchema: [ { key: 'max_results', type: 'number', label: 'Maximum Results', description: 'How many results to return', required: false, defaultValue: 10, min: 1, max: 100, }, ], }, ]; } ``` ### Field types | Type | Description | Type-specific properties | | ------------- | ---------------------- | ---------------------------------------------------- | | `string` | Single-line text | `minLength`, `maxLength`, `regex`, `placeholder` | | `text` | Multi-line text | `minLength`, `maxLength`, `rows`, `placeholder` | | `number` | Numeric input | `min`, `max`, `numberType` (`integer` or `float`) | | `boolean` | Toggle/checkbox | `defaultValue` | | `date` | Date picker | `minDate`, `maxDate` | | `select` | Single-choice dropdown | `options: [{value, label}]` | | `multiselect` | Multi-choice dropdown | `options: [{value, label}]`, `minItems`, `maxItems` | | `radio` | Radio button group | `options: [{value, label}]` | | `file` | File upload | `maxSize`, `allowedMimeTypes`, `maxFiles` | | `array` | Repeatable items | `itemField: {type, ...}`, `minItems`, `maxItems` | | `object` | Nested fields | `fields: [{key, type, ...}]` | | `objectArray` | Repeatable objects | `fields: [{key, type, ...}]`, `minItems`, `maxItems` | ### Common field properties | Property | Type | Description | | -------------- | ------- | ------------------------------------------------------- | | `key` | string | Unique field identifier (snake\_case or CONSTANT\_CASE) | | `type` | string | One of the field types above | | `label` | string | Display label shown to the user | | `description` | string | Help text below the field | | `placeholder` | string | Placeholder text inside the field | | `required` | boolean | Whether the field must be filled | | `defaultValue` | any | Pre-filled value | ### File upload field ```typescript theme={null} { key: 'document', type: 'file', label: 'Upload Document', description: 'PDF, Word, or text file to analyze', required: true, maxSize: 50 * 1024 * 1024, // 50 MB allowedMimeTypes: ['application/pdf', '.docx', '.doc', '.txt'], } ``` ### Select field ```typescript theme={null} { key: 'language', type: 'select', label: 'Output Language', required: true, defaultValue: 'english', options: [ { value: 'english', label: 'English' }, { value: 'french', label: 'French' }, { value: 'dutch', label: 'Dutch' }, ], } ``` ### Array field ```typescript theme={null} { key: 'urls', type: 'array', label: 'URLs to process', itemField: { type: 'string', maxLength: 500 }, minItems: 1, maxItems: 10, } ``` ## Output schemas Output schemas define the structure of execution results. They apply to **all trigger types**. ### Structure An output schema is a flat array of field definitions: ```typescript theme={null} function getOutputSchema(): FormOutputSchema { return [ { key: 'summary', type: 'text', label: 'Analysis Summary', description: 'AI-generated summary of the document', }, { key: 'confidence', type: 'number', label: 'Confidence Score', description: 'How confident the AI is in the analysis (0-100)', numberType: 'integer', }, { key: 'categories', type: 'array', label: 'Detected Categories', description: 'List of categories found in the document', itemField: { type: 'string' }, }, { key: 'generated_report', type: 'file', label: 'Generated Report', description: 'PDF report generated by the workflow', }, ]; } ``` ### Output field types | Type | Description | Notes | | --------- | ---------------- | ------------------------------------------------- | | `string` | Single-line text | Short text values | | `text` | Multi-line text | Long-form content, markdown | | `number` | Numeric value | Use `numberType: 'integer'` for whole numbers | | `boolean` | True/false | Binary results | | `date` | Date value | ISO 8601 format | | `file` | Uploaded file | References a `documentId` from Codika Upload File | | `array` | List of items | Requires `itemField` with type definition | ### Sub-workflow output schema Sub-workflows always have an empty output schema: ```typescript theme={null} outputSchema: [] ``` Data flows back to the parent workflow via the Execute Workflow node's return value. ## Connecting schemas to workflow nodes ### Input data in workflows For HTTP triggers, the user's form data arrives in the webhook payload. Extract it in a Code node: ```javascript theme={null} // In a Code node after Codika Init const webhookData = $('Webhook Trigger').first().json; const query = webhookData.body.payload.query; const maxResults = webhookData.body.payload.max_results || 10; ``` ### Output data in workflows The Codika Submit Result node sends the `resultData` back. It must match the output schema: ```javascript theme={null} // In a Code node before Codika Submit Result return { json: { results: { summary: 'Analysis complete...', confidence: 95, categories: ['finance', 'legal'], generated_report: documentId, // From Codika Upload File } } }; ``` ## Validation The CLI validates schemas via the `schema-types` use-case script: ```bash theme={null} codika verify use-case ./my-use-case ``` Checks: * All field types are valid * Required properties are present * `itemField` is defined for array types * Keys use valid naming conventions # Triggers Source: https://doc.codika.io/concepts/triggers The four trigger types that start workflow execution — HTTP, schedule, service event, and sub-workflow ## Overview Every workflow must have at least one trigger. The trigger type determines how the workflow starts, what data it receives, and how Codika Init registers the execution. | Trigger type | How it starts | Codika Init mode | User input? | | ----------------- | ----------------------------- | ------------------------------------- | ------------------- | | **HTTP** | User clicks button / API call | Extracts metadata from webhook | Yes (`inputSchema`) | | **Schedule** | Cron expression fires | Creates execution via API | No | | **Service event** | External service sends data | Creates execution via API | No | | **Sub-workflow** | Called by parent workflow | Not present (sub-workflows skip Init) | Via parent | ## HTTP triggers User-initiated execution via webhook. The user fills a form (defined by `inputSchema`), submits it, and waits for results. ### config.ts definition ```typescript theme={null} import type { HttpTrigger } from 'codika'; const webhookId = crypto.randomUUID(); const webhookUrl = `{{ORGSECRET_N8N_BASE_URL_TERCESORG}}/webhook/{{PROCDATA_PROCESS_ID_ATADCORP}}/{{USERDATA_PROCESS_INSTANCE_UID_ATADRESU}}/analyze`; { triggerId: webhookId, type: 'http' as const, url: webhookUrl, method: 'POST' as const, title: 'Analyze Document', description: 'Upload a document for AI analysis', inputSchema: getInputSchema(), } satisfies HttpTrigger ``` ### Workflow pattern ``` Webhook (responseMode: lastNode) → Codika Init (extracts execution metadata from webhook payload) → [Business logic] → Codika Submit Result ``` The webhook node must have `responseMode` set to `lastNode` so that Codika Submit Result returns data to the caller. **Agent access:** HTTP-triggered workflows are also callable via the public API (`codika trigger `) using an API key. Create an [agent skill](/concepts/agent-skills) to document the endpoint for AI agents — they'll know exactly how to call it without touching any credentials. ### n8n node configuration ```json theme={null} { "type": "n8n-nodes-base.webhook", "typeVersion": 2, "parameters": { "httpMethod": "POST", "path": "{{PROCDATA_PROCESS_ID_ATADCORP}}/{{USERDATA_PROCESS_INSTANCE_UID_ATADRESU}}/analyze", "responseMode": "lastNode", "options": {} }, "webhookId": "{{USERDATA_PROCESS_INSTANCE_UID_ATADRESU}}" } ``` ## Schedule triggers Automatic execution on a cron schedule. No user input — the workflow runs at the configured time. ### config.ts definition ```typescript theme={null} import type { ScheduleTrigger } from 'codika'; { triggerId: crypto.randomUUID(), type: 'schedule' as const, cronExpression: '0 8 * * 1-5', timezone: 'Europe/Brussels', humanReadable: 'Weekdays at 8:00 AM Brussels time', title: 'Daily Report', description: 'Generates and sends the daily summary report', } satisfies ScheduleTrigger ``` ### Common cron expressions | Expression | Schedule | | -------------- | ------------------------------------- | | `0 8 * * *` | Daily at 8:00 AM | | `0 9 * * 1` | Weekly on Monday at 9:00 AM | | `0 9 * * 1-5` | Weekdays at 9:00 AM | | `0 9 1,15 * *` | 1st and 15th of each month at 9:00 AM | | `*/5 * * * *` | Every 5 minutes | ### Workflow pattern Schedule triggers often include a manual webhook as a secondary trigger for testing: ``` Schedule Trigger ──┐ ├──→ Codika Init (creates execution via API) Manual Webhook ────┘ → [Business logic] → Codika Submit Result ``` ### n8n Codika Init configuration (schedule mode) ```json theme={null} { "type": "n8n-nodes-codika.codika", "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": "daily-report", "triggerType": "schedule" } } ``` **Key difference from HTTP triggers:** For schedule and service event triggers, Codika Init **creates** the execution record by calling the platform API. For HTTP triggers, it **extracts** the execution metadata from the incoming webhook payload. ## Service event triggers External services (Gmail, Calendly, WhatsApp, etc.) trigger the workflow when an event occurs. ### config.ts definition ```typescript theme={null} import type { ServiceEventTrigger } from 'codika'; { triggerId: crypto.randomUUID(), type: 'service_event' as const, service: 'email' as const, eventType: 'new_email_with_attachment', title: 'New Email with Attachment', description: 'Triggers when a new email with attachments arrives', } satisfies ServiceEventTrigger ``` ### Service event types | Service | Event type | What triggers it | | ---------- | --------------------------- | ------------------------------ | | `email` | `new_email_with_attachment` | Email arrives with attachments | | `email` | `new_email_received` | Any new email arrives | | `calendly` | `invitee_created` | New booking on Calendly | | `whatsapp` | `message_received` | WhatsApp message received | ### Workflow pattern ``` Service Trigger (e.g., Gmail polling) → Codika Init (creates execution via API, same as schedule mode) → [Business logic] → Codika Submit Result ``` **Important:** Access trigger data via `$('Trigger Name').first().json`, **not** via Codika Init output. The Init node only provides execution metadata. ### Webhook ID for service triggers Some service event triggers need a `webhookId` on the trigger node: ```json theme={null} { "webhookId": "{{USERDATA_PROCESS_INSTANCE_UID_ATADRESU}}" } ``` ## Sub-workflow triggers Sub-workflows are helper workflows called by parent workflows. They are not visible to users and cannot be triggered directly. ### config.ts definition ```typescript theme={null} import type { SubworkflowTrigger } from 'codika'; { triggerId: crypto.randomUUID(), type: 'subworkflow' as const, title: 'Process Text', description: 'Called by parent workflow to process text chunks', inputSchema: [ { key: 'text', type: 'string' }, { key: 'maxLength', type: 'number' }, { key: 'executionId', type: 'string' }, { key: 'executionSecret', type: 'string' }, ], calledBy: ['main-workflow'], } satisfies SubworkflowTrigger ``` ### Key rules * **No Codika Init** — sub-workflows do not register their own execution * **At least 1 input parameter** — n8n requires this * **Cost: 0** — execution cost is attributed to the parent workflow * **Output schema: \[]** — always empty (data flows back to parent via Execute Workflow node) * **Pass execution metadata** if the sub-workflow uses Codika Upload File See [Sub-Workflows guide](/guides/sub-workflows) for complete patterns. ## Multiple triggers per workflow A single workflow can have multiple triggers. Common patterns: * **Schedule + HTTP**: Automated daily run with a manual "run now" button * **Multiple HTTP**: Different entry points with different input schemas * **HTTP + Service event**: Manual run plus automatic triggering on events Each trigger gets its own `triggerId` in the config. # Use Cases Source: https://doc.codika.io/concepts/use-cases The fundamental deployment unit — a folder containing config, workflows, and metadata that defines a complete automation ## What is a use case? A use case is Codika's deployment unit. It is a folder on disk that contains everything needed to deploy one or more n8n workflows as a single automation to the Codika platform. When deployed, a use case becomes a **Process** that users can discover, install, and run with their own credentials. ## Folder structure ``` my-use-case/ config.ts # Required: deployment configuration version.json # Required: semantic version (auto-managed) project.json # Optional: platform project ID and org ID workflows/ main-workflow.json # Required: at least one workflow helper-workflow.json # Optional: sub-workflows skills/ # Optional: agent skills for triggerable workflows main-workflow/ SKILL.md # Claude-compatible skill file scheduled-report/ SKILL.md deployments/ # Auto-created: deployment archives {projectId}/ project-info.json process/ {apiVersion}/ deployment-info.json config-snapshot.json workflows/*.json ``` ### Required files | File | Purpose | | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- | | `config.ts` | Exports `WORKFLOW_FILES`, `getConfiguration()`, and optionally `getDeploymentInputSchema()` and `getDefaultDeploymentParameters()` | | `version.json` | Tracks the local semantic version (e.g., `{"version": "1.2.3"}`). Updated automatically on deploy. | | `workflows/*.json` | n8n workflow JSON files. Each file listed in `WORKFLOW_FILES` is packaged and sent to the platform. | ### Optional files | File | Purpose | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `project.json` | Contains `projectId`, `organizationId`, `devProcessInstanceId`, `prodProcessInstanceId`, and `deployments` map. Created by `codika init` or `codika project create --path .`. Updated on deploy and publish. | | `skills/` | Agent skill directories. Each subdirectory contains a `SKILL.md` file describing how to interact with a workflow. Automatically collected during deploy. See [Agent Skills](/concepts/agent-skills). | | `deployments/` | Local archive of past deployments. Created automatically by `codika deploy`. | ## config.ts structure The config file must export these members: ```typescript theme={null} import { loadAndEncodeWorkflow } from 'codika'; import { fileURLToPath } from 'url'; import { dirname } from 'path'; import crypto from 'crypto'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // Required: array of workflow file paths (relative to config.ts) export const WORKFLOW_FILES = [ 'workflows/main-workflow.json', 'workflows/helper-workflow.json', ]; // Required: returns the full deployment configuration export function getConfiguration(): ProcessDeploymentConfigurationInput { return { title: 'My Automation', subtitle: 'One-line description of what it does', description: 'Longer description of capabilities and benefits.', workflows: [ { workflowTemplateId: 'main-workflow', workflowId: 'main-workflow', workflowName: 'Main Workflow', integrationUids: ['anthropic', 'google_gmail'], triggers: [/* trigger definitions */], outputSchema: [/* output field definitions */], n8nWorkflowJsonBase64: loadAndEncodeWorkflow( __dirname, 'workflows/main-workflow.json' ), cost: 10, }, ], tags: ['email', 'ai'], }; } ``` ### Configuration fields | Field | Type | Required | Description | | --------------------------- | --------- | -------- | --------------------------------------- | | `title` | string | Yes | Display name (2-5 words) | | `subtitle` | string | No | One-line tagline | | `description` | string | Yes | 1-2 sentences describing the automation | | `workflows` | array | Yes | Array of workflow configurations | | `tags` | string\[] | No | Categorization tags | | `processDeploymentMarkdown` | string | No | Markdown documentation for the process | ### Workflow configuration fields | Field | Type | Required | Description | | ----------------------- | --------- | -------- | ------------------------------------------------------------- | | `workflowTemplateId` | string | Yes | Unique identifier for the workflow | | `workflowId` | string | Yes | Must match the `workflowId` parameter in Codika Init node | | `workflowName` | string | Yes | Display name | | `integrationUids` | string\[] | Yes | Required integrations (e.g., `['google_gmail', 'anthropic']`) | | `triggers` | array | Yes | At least one trigger definition | | `outputSchema` | array | Yes | Output field definitions (empty array `[]` for sub-workflows) | | `n8nWorkflowJsonBase64` | string | Yes | Base64-encoded workflow JSON | | `cost` | number | No | Execution cost in credits (0 for sub-workflows) | | `markdownInfo` | string | No | Workflow-specific documentation | ## Version management The `version.json` file tracks a semantic version: ```json theme={null} { "version": "1.2.3" } ``` On each deploy, the CLI: 1. Reads the current version 2. Bumps it based on the flag: `--patch` (default), `--minor`, or `--major` 3. Sends the API version to the platform (X.Y format) 4. Writes the new version back to `version.json` | Local bump | Example | API version strategy | | ---------------------- | -------------- | ------------------------ | | `--patch` (default) | 1.0.0 → 1.0.1 | `minor_bump` | | `--minor` | 1.0.1 → 1.1.0 | `minor_bump` | | `--major` | 1.1.0 → 2.0.0 | `major_bump` | | `--target-version 3.0` | Any → explicit | `explicit` (version 3.0) | ## Relationship to platform entities When you deploy a use case, the platform creates linked records: ``` Use case folder → Process (public listing, discoverable) → Deployment template (immutable version snapshot) → Process instance (user installation with settings and activation state) → Deployment instance (running copy with live n8n workflow IDs) ``` See [Processes](/concepts/processes) for full details on the deployment lifecycle. # Workflows Source: https://doc.codika.io/concepts/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 # API Keys & Authentication Source: https://doc.codika.io/dashboard/authentication Four ways to authenticate — API keys for dashboards and CLI, webhook signatures for external platforms, query parameters for headless services ## Authentication methods Codika supports four authentication methods on its public API: | | Instance Key (`ck_`) | Organization Key (`cko_`) | Webhook Signature (HMAC) | URL Query Param | | ---------------------- | ----------------------------------- | ---------------------------------- | ---------------------------------------------------------------- | --------------------------------------- | | **Created by** | Auto-generated per process instance | You create in the Codika dashboard | External platform (Resend, Stripe, etc.) | Same `ck_` instance key | | **Scope** | One specific process instance | Any instance in the organization | One specific workflow endpoint | One specific process instance | | **Best for** | Custom dashboards, apps | CLI, agents, CI/CD | External platforms that sign outbound webhooks | Platforms that can't set custom headers | | **Passed via** | `X-API-Key` header | `X-Process-Manager-Key` header | `webhook-signature` + `webhook-id` + `webhook-timestamp` headers | `?api_key=` in URL | | **Secret on the wire** | Yes | Yes | No (only a signature) | Yes (encrypted by HTTPS) | **For custom dashboards, use instance keys (`ck_`).** They're auto-generated, scoped to exactly one process instance, and require no setup beyond copying the key. **For external platforms that sign webhooks** (Resend, Stripe, GitHub, Clerk), use [webhook signature verification](/dashboard/webhook-signatures). The external platform creates the signing secret — you just paste it into Codika. **For platforms that can't set custom headers** (GCP Pub/Sub, IoT devices, simple webhook senders), use [URL query parameter authentication](#url-query-parameter-authentication). ## Where to find your instance API key 1. Open the Codika dashboard 2. Go to your process instance 3. Open the trigger panel (playground) 4. Find the "Public API Access" section 5. Copy the API key (format: `ck_...`) The API key is also visible in the cURL examples shown in the trigger panel. **Instance API keys are secrets.** Treat them like passwords. Never expose them in client-side code, public repositories, or browser network requests. ## Store keys server-side only Your custom app should **never** send the API key from the browser. Instead, proxy all Codika calls through your own server-side API routes. ``` Browser → Your API route (server-side, has API key) → Codika Public API ``` ### Example: SvelteKit server endpoint ```typescript theme={null} // src/routes/api/trigger/+server.ts import { json } from '@sveltejs/kit'; import { CODIKA_API_KEY, PROCESS_INSTANCE_ID } from '$env/static/private'; const TRIGGER_URL = `https://api.codika.io/webhook/${PROCESS_INSTANCE_ID}`; export async function POST({ request }) { const { workflowId, payload } = await request.json(); const response = await fetch(`${TRIGGER_URL}/${workflowId}`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': CODIKA_API_KEY }, body: JSON.stringify({ payload }) }); const data = await response.json(); return json(data); } ``` ### Example: Next.js API route ```typescript theme={null} // app/api/trigger/route.ts import { NextResponse } from 'next/server'; const CODIKA_API_KEY = process.env.CODIKA_API_KEY!; const PROCESS_INSTANCE_ID = process.env.PROCESS_INSTANCE_ID!; const TRIGGER_URL = `https://api.codika.io/webhook/${PROCESS_INSTANCE_ID}`; export async function POST(request: Request) { const { workflowId, payload } = await request.json(); const response = await fetch(`${TRIGGER_URL}/${workflowId}`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': CODIKA_API_KEY }, body: JSON.stringify({ payload }) }); const data = await response.json(); return NextResponse.json(data); } ``` ## Environment variables Store these in your `.env` file (gitignored): ```env theme={null} # Codika integration CODIKA_API_KEY=ck_your_instance_api_key_here PROCESS_INSTANCE_ID=your_process_instance_id_here # Base URLs (same for all instances) CODIKA_TRIGGER_BASE_URL=https://api.codika.io/webhook CODIKA_STATUS_BASE_URL=https://api.codika.io/status ``` ## Key regeneration If an instance API key is compromised, you can regenerate it from the Codika dashboard. The old key is immediately invalidated. Update your app's environment variables with the new key. ## When to use org keys instead Use `cko_` organization keys when your app needs to: * Access **multiple** process instances (not just one) * Deploy use cases programmatically * Read agent skills via the API * Operate across the organization For most custom dashboards that serve one use case, `ck_` instance keys are simpler and more secure (narrower scope). ## URL query parameter authentication Some platforms (GCP Pub/Sub, IoT devices, simple webhook senders) can only configure a URL — they can't set custom HTTP headers. For these, pass your instance API key as a query parameter: ``` POST https://api.codika.io/webhook/{processInstanceId}/{workflowId}?api_key=ck_your_key ``` This uses the same `ck_` instance key and the same validation — just a different delivery method. **Prefer headers when possible.** Query parameters can appear in server access logs and monitoring dashboards. Use this method only when the calling platform doesn't support custom headers. HTTPS encrypts the full URL in transit, so the key is protected on the wire. ### When to use query parameter auth | Platform | Can set headers? | Recommended auth | | ---------------------- | ---------------- | ------------------ | | Your own dashboard/app | Yes | `X-API-Key` header | | Resend, Stripe, GitHub | Yes (HMAC) | Webhook signatures | | GCP Pub/Sub push | No | Query parameter | | Simple IoT webhooks | No | Query parameter | | Zapier, Make | Yes | `X-API-Key` header | # Dev & Prod Environments Source: https://doc.codika.io/dashboard/environments Switch between development and production with separate process instances, API keys, and configurations ## How environments work Every Codika use case has two environments: | Environment | Purpose | Created when | | ----------- | ----------------------- | --------------------- | | **Dev** | Testing by the creator | First `codika deploy` | | **Prod** | Live usage by all users | `codika publish` | Each environment has its own: * **Process instance ID** — different URL path for triggers * **API key** (`ck_`) — different credentials * **n8n workflows** — separate copies with separate execution history ## Configuration pattern Structure your app's configuration around environments: ```typescript theme={null} interface CodikaConfig { apiKey: string; triggerBaseUrl: string; statusBaseUrl: string; } type AppMode = 'dev' | 'prod'; function getCodikaConfig(mode: AppMode): CodikaConfig { const instanceId = mode === 'dev' ? process.env.DEV_PROCESS_INSTANCE_ID : process.env.PROD_PROCESS_INSTANCE_ID; const apiKey = mode === 'dev' ? process.env.DEV_CODIKA_API_KEY : process.env.PROD_CODIKA_API_KEY; const baseUrl = 'https://api.codika.io'; return { apiKey: apiKey!, triggerBaseUrl: `${baseUrl}/webhook/${instanceId}`, statusBaseUrl: `${baseUrl}/status/${instanceId}` }; } ``` ## Environment variables ```env theme={null} # Dev environment DEV_PROCESS_INSTANCE_ID=019c8fb3-xxxx-dev DEV_CODIKA_API_KEY=ck_dev_xxxxxxxx # Prod environment PROD_PROCESS_INSTANCE_ID=019d1a2b-xxxx-prod PROD_CODIKA_API_KEY=ck_prod_xxxxxxxx ``` ## Where to find instance IDs * **Dev instance ID**: In `project.json` after deploying (`devProcessInstanceId`) * **Prod instance ID**: In `project.json` after publishing (`prodProcessInstanceId`) * **Both**: Visible in the Codika dashboard under your process ## Mode switching in your app A common pattern is to let the app creator toggle between dev and prod: ```typescript theme={null} // Store mode in a cookie or database function setMode(mode: AppMode) { document.cookie = `app_mode=${mode}; path=/; max-age=31536000`; } // Read mode on the server function getMode(cookies: Cookies): AppMode { return (cookies.get('app_mode') as AppMode) || 'prod'; } ``` Then use the mode to build the config on every request: ```typescript theme={null} // In your server hook or middleware const mode = getMode(event.cookies); const codikaConfig = getCodikaConfig(mode); // Pass to route handlers via locals, context, etc. ``` ## What changes between environments | | Dev | Prod | | ------------------------ | --------------------------------- | ---------------- | | Process instance ID | Different | Different | | Codika API key (`ck_`) | Different | Different | | Workflow versions | Latest deployed | Latest published | | Trigger/status base URLs | **Same** | **Same** | | Your own database | Up to you (can share or separate) | Up to you | The Codika base URLs are the same — only the process instance ID in the URL path changes. ## Typical flow 1. **Development**: Deploy use case → get dev instance ID and API key → test with your dashboard 2. **Ready for production**: Publish the use case → get prod instance ID and API key → update your `.env` 3. **New version**: Deploy again → dev updates automatically → test → publish → prod updates for all users 4. **Parameter changes**: Use `codika rerun deployment` to update parameters on dev or prod without creating a new version — only changed parameters are sent, and the platform merges them with existing values # Dashboard Integration Source: https://doc.codika.io/dashboard/overview Build custom frontends and dashboards on top of Codika use cases — trigger workflows, poll results, and manage environments via the public API ## Why build a custom dashboard? Codika deploys your workflows as stable HTTP endpoints with credential isolation and execution tracking. You can trigger these endpoints from **any frontend** — not just the Codika dashboard. This means you can build a custom app that: * Triggers your workflows from your own UI * Displays results in your own format * Manages its own users and data * Talks to your own database alongside Codika ## Architecture ``` Your App (SvelteKit, Next.js, any framework) → Your API routes (server-side, holds API key) → Codika Public API (trigger + poll) → n8n workflow (business logic, integrations) → Result returned to your app ``` **What Codika provides:** * Stable HTTP endpoints per workflow (don't change across versions) * Credential isolation (your app never sees integration tokens) * Execution tracking (trigger, poll status, get results) * Dev/prod environments with separate instance IDs and API keys * Secured n8n endpoints (workflows are only callable through the Codika API, not directly) **What you build:** * The frontend (UI, forms, data display) * Your own database (users, audit logs, app-specific data) * Server-side API routes that proxy to Codika (keeps API key private) * Business logic around the workflow results ## The integration is simple Your app only needs three things from Codika: | What | How | | ------------------------- | ---------------------------------------------------------------------------------------- | | **Trigger a workflow** | `POST triggerWebhookPublic/{processInstanceId}/{workflowId}` with `X-API-Key` header | | **Poll for results** | `GET getExecutionStatusPublic/{processInstanceId}/{executionId}` with `X-API-Key` header | | **Know what's available** | Agent skills describe each endpoint's input/output (optional but helpful) | That's it. Two endpoints, one API key, and you can build anything on top. ## Next steps Understand the two API key types and how to store them securely. The core pattern: trigger a workflow, poll for results, parse the output. Switch between dev and prod with separate instance IDs and API keys. Error handling, retry logic, audit trails, and security best practices. # Common Patterns Source: https://doc.codika.io/dashboard/patterns Error handling, retry logic, audit trails, and security best practices for dashboard integrations ## Error handling ### Trigger failures The trigger endpoint can fail for several reasons: ```typescript theme={null} const response = await fetch(triggerUrl, { method: 'POST', ... }); if (!response.ok) { const text = await response.text(); // Handle by status code switch (response.status) { case 401: // Invalid API key case 403: // API key doesn't have access to this instance case 404: // Process instance or workflow not found case 500: // Platform error } } ``` ### Polling failures The status endpoint may be temporarily unavailable while the execution is being registered. **Don't treat transient errors as fatal** — continue polling: ```typescript theme={null} while (Date.now() - startTime < maxWaitMs) { await sleep(pollIntervalMs); const response = await fetch(statusUrl, { headers: { 'X-API-Key': apiKey } }); // Transient error — keep polling if (!response.ok) continue; const data = await response.json(); const status = data.execution?.status; if (status === 'pending') continue; if (status === 'success') return parseResult(data.execution.resultData); if (status === 'failed') throw new Error(data.execution.errorDetails?.message); } throw new Error('Timed out'); ``` ### Execution failures When a workflow fails, the error details are in `execution.errorDetails`: ```json theme={null} { "execution": { "status": "failed", "errorDetails": { "message": "External API returned 429: Rate limit exceeded", "type": "external_api_error" } } } ``` Error types: `node_failure`, `validation_error`, `external_api_error`, `timeout` ## Result parsing with fallbacks Workflow output shapes can vary. Always validate before assuming structure: ```typescript theme={null} function parseResult(resultData: unknown): MyResult { if (resultData && typeof resultData === 'object') { const data = resultData as Record; // Try to parse expected shape if (typeof data.result === 'string') { return { result: data.result, processedAt: data.processedAt as string }; } } // Fallback for unexpected shapes return { result: JSON.stringify(resultData), processedAt: new Date().toISOString() }; } ``` ## Retry logic ### Retrying failed items in a batch If a workflow processes multiple items and some fail, retry only the failures: ```typescript theme={null} const result = await triggerAndPoll('batch-send', { phone_numbers: allNumbers, message: 'Hello' }); // Find failures const failed = result.results.filter(r => r.status === 'failed'); if (failed.length > 0) { // Retry only failed items const retryResult = await triggerAndPoll('batch-send', { phone_numbers: failed.map(f => f.phone), message: 'Hello' }); } ``` ### Idempotency Codika workflows are **not idempotent by default**. Retrying a trigger creates a new execution. If your workflow has side effects (sending messages, creating records), design your retry logic accordingly: * Track which items succeeded before retrying * Use your own database to record trigger history * Don't blindly re-trigger the entire batch ## Audit trail Log every workflow trigger and result to your own database for accountability: ```typescript theme={null} async function triggerWithAudit( workflowId: string, payload: Record, initiatedBy: string ) { // 1. Create audit record const auditId = await db.insert('workflow_triggers', { workflowId, payload: JSON.stringify(payload), initiatedBy, triggeredAt: new Date(), status: 'triggered' }); // 2. Trigger and poll try { const executionId = await triggerWorkflow(workflowId, payload); const result = await pollExecution(executionId); // 3. Update audit record await db.update('workflow_triggers', auditId, { executionId, status: result.status, resultData: JSON.stringify(result.data), completedAt: new Date() }); return result; } catch (error) { await db.update('workflow_triggers', auditId, { status: 'error', error: error.message, completedAt: new Date() }); throw error; } } ``` ## Security best practices ### Keep API keys server-side Never expose the Codika API key in client-side code. All calls to Codika should go through your server: ``` Browser → Your API route → Codika Public API ``` Your API route handles: * Authentication of your own users (session, JWT, etc.) * Authorization (can this user trigger this workflow?) * API key injection (adds the X-API-Key header) * Response filtering (only return what the client needs) ### Query parameter security When using `?api_key=` query parameter authentication: * **HTTPS encrypts the full URL** including query parameters — the key is protected in transit * **Server logs may record query strings** — ensure your log retention and access controls are appropriate * **Use instance keys (`ck_`)**, not organization keys — instance keys have the narrowest scope * **Rotate keys** if you suspect exposure — regenerate from the Codika dashboard ### Validate input before triggering Don't pass raw user input to the workflow. Validate and sanitize on your server before calling the trigger endpoint: ```typescript theme={null} export async function POST({ request, locals }) { const { message, recipients } = await request.json(); // Validate if (!message || message.length > 4096) { return json({ error: 'Invalid message' }, { status: 400 }); } if (!Array.isArray(recipients) || recipients.length > 500) { return json({ error: 'Invalid recipients' }, { status: 400 }); } // Sanitized payload const payload = { message_content: message.trim(), phone_numbers: recipients.map(r => r.replace(/\D/g, '')) }; // Trigger const executionId = await triggerWorkflow('batch-send', payload); return json({ executionId }); } ``` ### Rate limit your own endpoints Codika doesn't rate-limit workflow triggers beyond n8n's capacity. Add rate limiting to your own API routes to prevent abuse: ```typescript theme={null} // Example: max 10 triggers per minute per user const rateLimiter = new RateLimiter({ maxRequests: 10, windowMs: 60_000 }); export async function POST({ request, locals }) { if (!rateLimiter.allow(locals.userId)) { return json({ error: 'Too many requests' }, { status: 429 }); } // ... trigger workflow } ``` ## Polling configuration Tune polling parameters based on your workflow's expected duration: | Workflow type | Suggested interval | Suggested timeout | | ------------------------------------- | ------------------ | ----------------- | | Fast (validation, lookup) | 1s | 30s | | Medium (API calls, processing) | 1.5s | 120s | | Slow (AI generation, file processing) | 3s | 300s | Start with 1.5s interval / 120s timeout and adjust based on actual execution times. # Triggering Workflows Source: https://doc.codika.io/dashboard/triggering-workflows The trigger and poll pattern — fire a workflow, track its execution, and parse the results ## The two endpoints Your app uses two Codika public API endpoints: | Endpoint | Method | Purpose | | ------------------------------------------ | ------ | --------------------- | | `webhook/{processInstanceId}/{workflowId}` | POST | Trigger a workflow | | `status/{processInstanceId}/{executionId}` | GET | Poll execution status | Both require authentication — an `X-API-Key` header, [webhook signature headers](/dashboard/webhook-signatures), or a [query parameter](/dashboard/authentication#url-query-parameter-authentication). ## Step 1: Trigger a workflow ``` POST https://api.codika.io/webhook/{processInstanceId}/{workflowId} Headers: Content-Type: application/json X-API-Key: ck_your_instance_key Body: { "payload": { "field1": "value1", "field2": "value2" } } ``` The `payload` fields must match the workflow's input schema (defined in `config.ts`). ### Query parameter variant For platforms that can't set custom headers (e.g., GCP Pub/Sub push subscriptions): ``` POST https://api.codika.io/webhook/{processInstanceId}/{workflowId}?api_key=ck_your_key Headers: Content-Type: application/json Body: { "payload": { ... } } ``` See [URL query parameter authentication](/dashboard/authentication#url-query-parameter-authentication) for details. If your platform signs outbound webhooks (like Resend, Stripe, or any Standard Webhooks-compatible system), you can use **HMAC signature verification** instead of API keys. See [Webhook Signature Verification](/dashboard/webhook-signatures). ### Response ```json theme={null} { "success": true, "executionId": "019c8fb3-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "message": "Execution started" } ``` Save the `executionId` — you'll need it for polling. ### The `workflowId` This is the `workflowTemplateId` from the use case's `config.ts`. It's a stable identifier that doesn't change across versions. Examples: `main-workflow`, `http-direct-messaging`, `scheduled-report`. If the use case has agent skills, each skill's `workflowTemplateId` field tells you the ID to use. ## Step 2: Poll for results ``` GET https://api.codika.io/status/{processInstanceId}/{executionId} Headers: X-API-Key: ck_your_instance_key ``` ### Response ```json theme={null} { "execution": { "status": "success", "resultData": { "result": "Processed output", "processedAt": "2025-03-15T10:30:00.000Z" } } } ``` ### Status values | Status | Meaning | Action | | --------- | ------------------------------- | ------------------------------------- | | `pending` | Workflow is still running | Continue polling | | `success` | Workflow completed successfully | Read `execution.resultData` | | `failed` | Workflow encountered an error | Read `execution.errorDetails.message` | ## Complete trigger + poll implementation Here's a reusable implementation in TypeScript: ```typescript theme={null} interface TriggerResult { executionId: string; } interface ExecutionResult { status: 'success' | 'failed'; data?: T; error?: string; } const TRIGGER_BASE = 'https://api.codika.io/webhook'; const STATUS_BASE = 'https://api.codika.io/status'; /** * Trigger a workflow and return the execution ID. */ async function triggerWorkflow( processInstanceId: string, workflowId: string, payload: Record, apiKey: string ): Promise { const response = await fetch( `${TRIGGER_BASE}/${processInstanceId}/${workflowId}`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': apiKey }, body: JSON.stringify({ payload }) } ); if (!response.ok) { const text = await response.text(); throw new Error(`Trigger failed (${response.status}): ${text}`); } const data = await response.json(); const executionId = data.executionId ?? data.id; if (!executionId) { throw new Error('No executionId in trigger response'); } return executionId; } /** * Poll until the execution completes or times out. */ async function pollExecution( processInstanceId: string, executionId: string, apiKey: string, parseResult: (resultData: unknown) => T, options?: { maxWaitMs?: number; pollIntervalMs?: number } ): Promise> { const maxWait = options?.maxWaitMs ?? 120_000; const interval = options?.pollIntervalMs ?? 1_500; const startTime = Date.now(); while (Date.now() - startTime < maxWait) { await new Promise(resolve => setTimeout(resolve, interval)); const response = await fetch( `${STATUS_BASE}/${processInstanceId}/${executionId}`, { headers: { 'X-API-Key': apiKey } } ); if (!response.ok) continue; // Retry on transient errors const data = await response.json(); const status = data.execution?.status; if (status === 'pending') continue; if (status === 'success') { return { status: 'success', data: parseResult(data.execution.resultData) }; } if (status === 'failed') { return { status: 'failed', error: data.execution.errorDetails?.message ?? 'Unknown error' }; } } throw new Error(`Execution timed out after ${maxWait / 1000}s`); } ``` ### Usage ```typescript theme={null} // Trigger const executionId = await triggerWorkflow( PROCESS_INSTANCE_ID, 'http-direct-messaging', { phone_numbers: ['32477123456'], message_content: 'Hello!' }, CODIKA_API_KEY ); // Poll and parse const result = await pollExecution( PROCESS_INSTANCE_ID, executionId, CODIKA_API_KEY, (data) => data as { success: boolean; total_sent: number } ); if (result.status === 'success') { console.log(`Sent to ${result.data.total_sent} recipients`); } else { console.error(`Failed: ${result.error}`); } ``` ## Payload format The trigger endpoint wraps your input in a `payload` field: ```json theme={null} { "payload": { "text_input": "Hello world", "processing_mode": "summarize" } } ``` The keys inside `payload` must match the workflow's `inputSchema` field names. The `payload` wrapper is recommended but not required. If no `payload` key is present, the entire request body is passed through as-is. However, using the wrapper is safer and consistent with how the Codika dashboard sends data. ## Workflows without input Some workflows (like scheduled reports with manual triggers) don't require input. Send an empty body or empty payload: ```typescript theme={null} const executionId = await triggerWorkflow( PROCESS_INSTANCE_ID, 'scheduled-report', {}, CODIKA_API_KEY ); ``` # Webhook Signature Verification Source: https://doc.codika.io/dashboard/webhook-signatures Authenticate requests using HMAC-SHA256 signatures — the standard used by Resend, Stripe, and other webhook platforms ## When to use this If the system calling your Codika endpoint **signs outbound webhooks automatically** (like Resend, Stripe, GitHub, Clerk, or any Svix-based platform), use webhook signature verification instead of API keys. | | API Key (`X-API-Key`) | Webhook Signature (HMAC) | | ------------------------- | ------------------------------------------ | -------------------------------------------------------- | | **Best for** | Your own dashboards, curl, Postman, Zapier | External platforms that sign webhooks | | **Setup** | Copy key, paste in header | Register URL in platform, paste signing secret in Codika | | **Secret on the wire** | Yes (key sent in every request) | No (only a signature derived from the secret) | | **Replay protection** | No | Yes (5-minute timestamp window) | | **Body tamper detection** | No | Yes (body is part of the signed payload) | ## How it works Codika follows the [Standard Webhooks](https://www.standardwebhooks.com/) specification (used by Resend, Clerk, Dub, and others). When the external platform sends a request to your Codika endpoint, it includes three headers: | Header | Purpose | Example | | ------------------- | ------------------------- | --------------------- | | `webhook-id` | Unique message identifier | `msg_2xK9a8B...` | | `webhook-timestamp` | Unix timestamp (seconds) | `1711987200` | | `webhook-signature` | HMAC-SHA256 signature | `v1,K7gNU3sdo+OL0...` | The signature is computed as: ``` HMAC-SHA256( key: base64_decode(signing_secret), message: "{webhook-id}.{webhook-timestamp}.{request_body}" ) ``` Codika verifies the signature and rejects the request if: * The signature doesn't match (tampered body or wrong secret) * The timestamp is older than 5 minutes (replay attack) * No signing secret is configured for that endpoint ## Setup ### Step 1: Get your webhook URL Open the **API Access** sheet from your process instance card (click the key icon). Each HTTP endpoint shows its public URL: ``` https://api.codika.io/webhook/{processInstanceId}/{workflowId} ``` Copy this URL. ### Step 2: Register the URL in your external platform Paste the Codika webhook URL in your platform's webhook configuration. When you save, the platform generates a **signing secret** (typically prefixed `whsec_`). ### Step 3: Paste the signing secret into Codika Back in Codika's API Access sheet, find the endpoint you registered and paste the signing secret in the "Signing Secrets" section. Optionally add a label (e.g., "Resend production"). That's it. The external platform will now sign every request, and Codika will verify it automatically. ## Sending signed requests manually If you're building your own webhook delivery system, here's how to sign requests: ### TypeScript / Node.js ```typescript theme={null} import crypto from 'crypto'; async function sendSignedWebhook( url: string, signingSecret: string, payload: object ) { const body = JSON.stringify(payload); const msgId = `msg_${crypto.randomUUID().split('-')[0]}`; const timestamp = Math.floor(Date.now() / 1000).toString(); // Strip whsec_ prefix and base64-decode the secret const secretBase64 = signingSecret.replace('whsec_', ''); const secretKey = Buffer.from(secretBase64, 'base64'); // Sign: HMAC-SHA256("{msg_id}.{timestamp}.{body}") const signature = crypto .createHmac('sha256', secretKey) .update(`${msgId}.${timestamp}.${body}`) .digest('base64'); const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'webhook-id': msgId, 'webhook-timestamp': timestamp, 'webhook-signature': `v1,${signature}` }, body }); return response.json(); } ``` ### cURL ```bash theme={null} TIMESTAMP=$(date +%s) BODY='{"event":"invoice.paid","data":{"id":"inv_42"}}' MSG_ID="msg_test123" SECRET_B64="your_base64_secret_here" # The part after whsec_ SIGNATURE=$(echo -n "${MSG_ID}.${TIMESTAMP}.${BODY}" \ | openssl dgst -sha256 -hmac "$(echo ${SECRET_B64} | base64 -d)" -binary \ | base64) curl -X POST \ -H "Content-Type: application/json" \ -H "webhook-id: ${MSG_ID}" \ -H "webhook-timestamp: ${TIMESTAMP}" \ -H "webhook-signature: v1,${SIGNATURE}" \ https://api.codika.io/webhook/{processInstanceId}/{workflowId} \ -d "${BODY}" ``` ## Payload format When using webhook signatures, the request body is passed through **as-is** to the workflow. There's no need for the `{"payload": {...}}` wrapper used with API key authentication — Codika handles both formats. ## Multiple secrets per endpoint Each endpoint can have multiple signing secrets. This is useful for: * **Secret rotation**: Add the new secret, update the external platform, then remove the old one. Both secrets are valid during the transition. * **Multiple sources**: Different systems can send to the same endpoint, each with their own signing secret. Codika checks all stored secrets for a given endpoint and accepts the request if any one matches. ## Mixing auth methods All authentication methods coexist on the same endpoint. Codika checks in order: 1. **Webhook signature headers** (HMAC) — if `webhook-signature`, `webhook-id`, and `webhook-timestamp` headers are present 2. **API key in headers** — `X-API-Key` or `Authorization: Bearer` 3. **API key in query parameter** — `?api_key=` in the URL 4. **Organization key** — `X-Process-Manager-Key` header The first match wins. You can use different methods for different callers on the same endpoint. ## Security advantages * **The secret never travels on the wire.** Only a signature (derived from the secret) is sent. Even if someone intercepts the request, they can't extract the secret. * **Replay protection.** Requests older than 5 minutes are rejected, preventing captured requests from being replayed later. * **Tamper detection.** The request body is part of the signed message. Any modification to the body invalidates the signature. # Proposal Generator (RAG) Source: https://doc.codika.io/examples/complex-rag Complex multi-workflow use case with RAG retrieval, AI generation, sub-workflow PDF conversion, file uploads, and data ingestion ## Overview | Property | Value | | ---------------- | ---------------------------------------------------------------------------------- | | Workflows | 3 (2 parent + 1 sub-workflow) | | Triggers | HTTP (2 parent workflows) + sub-workflow | | Integrations | Anthropic (Claude), Pinecone (vector DB) | | Credential types | FLEXCRED (Anthropic), INSTCRED (Pinecone) | | Features | RAG retrieval, file upload/download, sub-workflows, data ingestion, knowledge base | | Cost | 15 + 5 + 0 credits | | Complexity | Complex | This use case generates business proposals by searching a knowledge base of historical proposals (via RAG), then using Claude to draft a new proposal based on the requirements document and similar past work. ## Folder structure ``` proposal-generation/ config.ts version.json project.json workflows/ proposal-generation-package.json # Main: generates proposal document-retrieval.json # RAG: finds similar documents markdown-to-pdf-subworkflow.json # Sub-workflow: converts to PDF ``` ## Workflow architecture ``` User uploads requirements document → proposal-generation-package (HTTP trigger) → Extract text from document → Search knowledge base (Pinecone) for similar proposals → Generate proposal with Claude (using similar docs as context) → Call pdf-converter sub-workflow → markdown-to-pdf-subworkflow → Convert markdown to PDF → Upload PDF via Codika Upload File (with execution metadata override) → Return documentId to parent → Codika Submit Result (with PDF documentId) User can also: → document-retrieval (HTTP trigger) → Search knowledge base without generating a proposal → Return matching documents ``` ## config.ts highlights ### Three workflow definitions ```typescript theme={null} export const WORKFLOW_FILES = [ 'workflows/proposal-generation-package.json', 'workflows/document-retrieval.json', 'workflows/markdown-to-pdf-subworkflow.json', ]; ``` ### Main workflow (HTTP trigger with file upload input) ```typescript theme={null} { workflowTemplateId: 'proposal-generation-package', workflowId: 'proposal-generation-package', workflowName: 'Generate Proposal', integrationUids: ['anthropic'], triggers: [{ triggerId: crypto.randomUUID(), type: 'http' as const, url: webhookUrl, method: 'POST' as const, title: 'Generate Proposal', inputSchema: getProposalInputSchema(), }], outputSchema: getProposalOutputSchema(), cost: 15, } ``` ### File input schema ```typescript theme={null} function getProposalInputSchema(): FormInputSchema { return [ { type: 'section', title: 'Proposal Configuration', collapsible: false, inputSchema: [ { key: 'requirements_file', type: 'file', label: 'Requirements Document', description: 'Upload the RFP or requirements document', required: true, maxSize: 50 * 1024 * 1024, allowedMimeTypes: ['application/pdf', '.docx', '.doc'], }, { key: 'proposal_language', type: 'select', label: 'Proposal Language', required: true, defaultValue: 'french', options: [ { value: 'french', label: 'French' }, { value: 'english', label: 'English' }, { value: 'dutch', label: 'Dutch' }, ], }, ], }, { type: 'section', title: 'Additional Context', collapsible: true, inputSchema: [ { key: 'notes', type: 'array', label: 'Additional Notes', description: 'Extra context to include in the proposal', itemField: { type: 'text', maxLength: 10000, rows: 6 }, minItems: 0, maxItems: 10, }, ], }, ]; } ``` ### File output schema ```typescript theme={null} function getProposalOutputSchema(): FormOutputSchema { return [ { key: 'proposal_pdf', type: 'file', label: 'Generated Proposal', description: 'PDF proposal document', }, { key: 'executive_summary', type: 'text', label: 'Executive Summary', }, ]; } ``` ### Sub-workflow definition ```typescript theme={null} { workflowTemplateId: 'markdown-to-pdf-subworkflow', workflowId: 'markdown-to-pdf-subworkflow', workflowName: 'Markdown to PDF Converter', integrationUids: [], triggers: [{ triggerId: crypto.randomUUID(), type: 'subworkflow' as const, title: 'Convert Markdown to PDF', inputSchema: [ { key: 'markdownContent', type: 'string' }, { key: 'fieldKey', type: 'string' }, { key: 'fileName', type: 'string' }, { key: 'executionId', type: 'string' }, { key: 'executionSecret', type: 'string' }, { key: 'docTitle', type: 'string' }, { key: 'docSubtitle', type: 'string' }, ], calledBy: ['proposal-generation-package'], }], outputSchema: [], cost: 0, } ``` ### Knowledge base access ```typescript theme={null} knowledgeBaseAccess: { processDocTags: ['proposal', 'rfp'], processInstanceDocTags: ['proposal'], } ``` This enables the workflow to access tagged documents from both the process-level and instance-level knowledge bases. ### Data ingestion configuration For embedding documents into the vector store: ```typescript theme={null} export function getDataIngestionConfig(): ProcessDataIngestionConfigInput { return { workflowTemplateId: 'proposal-embedding-ingestion', workflowName: 'Embedding Ingestion', n8nWorkflowJsonBase64: loadAndEncodeWorkflow(__dirname, 'workflows/embedding-workflow.json'), webhooks: { embed: '{{PROCDATA_PROCESS_ID_ATADCORP}}/embed', delete: '{{PROCDATA_PROCESS_ID_ATADCORP}}/embed-delete', }, purpose: 'Embed KB documents into Pinecone for RAG retrieval', cost: 2, }; } ``` ## Key patterns demonstrated ### 1. Multi-workflow architecture Three workflows with clear separation of concerns — main generation, retrieval, and PDF conversion. ### 2. Sub-workflow with file upload The PDF sub-workflow receives execution metadata from the parent and uses `executionIdOverride` / `executionSecretOverride` on the Codika Upload File node. ### 3. SUBWKFL placeholder Parent calls sub-workflow via: ```json theme={null} "value": "{{SUBWKFL_markdown-to-pdf-subworkflow_LFKWBUS}}" ``` ### 4. File input and output Users upload a document (requirements file), the workflow processes it, generates a PDF, uploads it via Codika Upload File, and returns the `documentId` as a `file` type output field. ### 5. RAG data ingestion Separate data ingestion workflow embeds documents into Pinecone. Deployed independently via: ```bash theme={null} codika deploy process-data-ingestion ./proposal-generation ``` ### 6. Knowledge base tags Documents are filtered by tags, allowing fine-grained access control over which documents the workflow can read. ### 7. Cost differentiation Main workflow costs 15 credits, retrieval costs 5, sub-workflow costs 0 (attributed to parent). ## Deploy sequence ```bash theme={null} # 1. Validate codika verify use-case ./proposal-generation # 2. Deploy use case (all 3 workflows) codika deploy use-case ./proposal-generation # 3. Deploy data ingestion (separate) codika deploy process-data-ingestion ./proposal-generation # 4. Test retrieval codika trigger document-retrieval --poll --payload-file - <<'EOF' {"query": "software development proposal"} EOF # 5. Test full generation (with file upload via platform UI) # File uploads require the platform UI — CLI trigger only supports JSON payloads ``` # Email Automation Source: https://doc.codika.io/examples/email-automation Service event triggered workflow that automatically organizes Gmail attachments into Google Drive and logs them to Sheets ## Overview | Property | Value | | ---------------- | ------------------------------------------------------------- | | Workflows | 1 | | Trigger | Service event (`new_email_with_attachment`) | | Integrations | Google Gmail, Google Drive, Google Sheets | | Credential types | USERCRED (Gmail, Drive, Sheets), INSTPARM (deployment params) | | Cost | 10 credits | | Complexity | Medium | This use case monitors a user's Gmail inbox for emails with attachments, saves them to Google Drive, and logs metadata to a Google Sheet. It runs automatically whenever a matching email arrives. ## Folder structure ``` gmail-attachment-organizer/ config.ts version.json project.json workflows/ gmail-attachment-processor.json ``` ## config.ts highlights ### Trigger definition (service event) ```typescript theme={null} { triggerId: crypto.randomUUID(), type: 'service_event' as const, service: 'email' as const, eventType: 'new_email_with_attachment', title: 'New Email with Attachment', description: 'Triggers when a new email with one or more attachments arrives', } ``` No `inputSchema` — service events do not accept user input per execution. ### Deployment parameters Users configure these at install time: ```typescript theme={null} export function getDeploymentInputSchema(): DeploymentInputSchema { return [ { key: 'DRIVE_FOLDER_NAME', type: 'string', label: 'Drive Folder Name', description: 'Name of the Google Drive folder to save attachments to', placeholder: 'Email Attachments', required: true, defaultValue: 'Email Attachments', }, { key: 'GMAIL_LABEL_NAME', type: 'string', label: 'Gmail Label', description: 'Label to apply to processed emails', placeholder: 'Processed', required: true, defaultValue: 'Processed', }, { key: 'SHEET_NAME', type: 'string', label: 'Spreadsheet Name', description: 'Name of the Google Sheet to log attachment metadata', placeholder: 'Attachment Log', required: true, defaultValue: 'Attachment Log', }, ]; } ``` ### Integration requirements ```typescript theme={null} integrationUids: ['google_gmail', 'google_drive', 'google_sheets'], ``` Each user must connect their own Google accounts. Credentials are per-user via USERCRED placeholders. ### Output schema ```typescript theme={null} function getOutputSchema(): FormOutputSchema { return [ { key: 'files_saved', type: 'number', label: 'Files Saved', numberType: 'integer', }, { key: 'sender', type: 'string', label: 'Sender Email', }, { key: 'drive_folder_id', type: 'string', label: 'Drive Folder ID', }, { key: 'spreadsheet_id', type: 'string', label: 'Spreadsheet ID', }, ]; } ``` ## Workflow pattern ``` Gmail Trigger (polling) → Codika Init (API mode) → Get Attachments → Save to Drive → Log to Sheet → IF Success → Submit Result → IF Error → Report Error ``` ### Codika Init (service event mode) Because this is a service event trigger (not HTTP), Codika Init creates the execution by calling the platform API: ```json theme={null} { "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": "gmail-attachment-processor", "triggerType": "gmail" } } ``` ### INSTPARM usage in Code nodes ```javascript theme={null} const folderName = {{INSTPARM_DRIVE_FOLDER_NAME_MRAPTSNI}}; const labelName = {{INSTPARM_GMAIL_LABEL_NAME_MRAPTSNI}}; const sheetName = {{INSTPARM_SHEET_NAME_MRAPTSNI}}; ``` ### USERCRED credentials ```json theme={null} "credentials": { "gmailOAuth2": { "id": "{{USERCRED_GOOGLE_GMAIL_ID_DERCRESU}}", "name": "{{USERCRED_GOOGLE_GMAIL_NAME_DERCRESU}}" } } ``` ## Key patterns demonstrated 1. **Service event trigger** — automatic execution on external events 2. **USERCRED** — per-user OAuth credentials (each user's own Gmail/Drive/Sheets) 3. **INSTPARM** — deployment parameters configured at install time 4. **Codika Init API mode** — creates execution record for non-HTTP triggers 5. **Multiple Google integrations** — coordinating Gmail, Drive, and Sheets # Examples Overview Source: https://doc.codika.io/examples/overview Gallery of 4 production use cases at different complexity levels — from a minimal web search tool to a multi-workflow RAG proposal generator ## Example gallery These examples are based on production use cases deployed on the Codika platform. They demonstrate different trigger types, integration patterns, AI capabilities, and complexity levels. | Example | Complexity | Triggers | Key features | | -------------------------------------------------- | ---------- | --------------- | ---------------------------------------------------------------- | | [Simple Web Search](/examples/simple-search) | Minimal | HTTP | Single workflow, one API call, FLEXCRED credentials | | [Email Automation](/examples/email-automation) | Medium | Service event | Gmail integration, Google Drive/Sheets, INSTPARM parameters | | [Scheduled CRM Report](/examples/scheduled-report) | Medium | Schedule + HTTP | Dual triggers, Slack integration, deployment parameters | | [Proposal Generator (RAG)](/examples/complex-rag) | Complex | HTTP | Multi-workflow, sub-workflows, RAG, file uploads, data ingestion | ## Patterns demonstrated ### Trigger types * **HTTP webhook** — user-initiated via form (Simple Search, Proposal Generator) * **Schedule (cron)** — time-based automation (CRM Report) * **Service event** — external service triggers (Email Automation) * **Sub-workflow** — helper called by parent (Proposal Generator) ### Credential types * **FLEXCRED** — AI providers with org/Codika fallback (all AI examples) * **USERCRED** — User's OAuth tokens (Email Automation) * **ORGCRED** — Organization-level shared credentials (CRM Report) * **INSTPARM** — User-configured deployment parameters (Email Automation, CRM Report) ### AI patterns * **chainLlm** — Structured classification with output parser (Email Intelligence) * **RAG retrieval** — Pinecone vector search for similar documents (Proposal Generator) * **Text generation** — Claude-powered content creation (Proposal Generator) ### Advanced patterns * **Multiple triggers** — Schedule + manual HTTP on same workflow (CRM Report) * **Sub-workflows** — PDF generation as a reusable helper (Proposal Generator) * **File uploads** — Generate and return files to users (Proposal Generator) * **Data ingestion** — Document embedding pipeline for RAG (Proposal Generator) * **Deployment parameters** — User-configurable installation settings (Email, CRM) ## Folder structure patterns ### Minimal (1 workflow) ``` simple-search/ config.ts version.json project.json workflows/ web-search.json ``` ### Standard (1-2 workflows) ``` email-automation/ config.ts version.json project.json workflows/ email-processor.json ``` ### Complex (multiple workflows + sub-workflows) ``` proposal-generator/ config.ts version.json project.json workflows/ proposal-generation.json document-retrieval.json pdf-converter.json # Sub-workflow ``` # Scheduled CRM Report Source: https://doc.codika.io/examples/scheduled-report Dual-trigger workflow (schedule + manual HTTP) that pulls Folk CRM pipeline data and posts a summary to Slack ## Overview | Property | Value | | ---------------- | --------------------------------------------------- | | Workflows | 1 | | Triggers | Schedule (cron) + HTTP (manual) | | Integrations | Folk CRM, Slack | | Credential types | ORGCRED (Folk, Slack), INSTPARM (deployment params) | | Cost | 30 credits | | Complexity | Medium | This use case runs daily at 9 AM (configurable) to pull pipeline data from Folk CRM and post a formatted report to a Slack channel. It also has a manual trigger for on-demand reports. ## Folder structure ``` folk-funnel-slack-reporter/ config.ts version.json project.json workflows/ folk-stats-to-slack.json ``` ## config.ts highlights ### Dual triggers ```typescript theme={null} const workflows = [ { workflowTemplateId: 'folk-stats-to-slack', triggers: [ { triggerId: manualTriggerId, type: 'http' as const, url: webhookUrl, method: 'POST' as const, title: 'Generate Report Now', description: 'Manually trigger a pipeline report', inputSchema: getManualTriggerInputSchema(), } satisfies HttpTrigger, { triggerId: scheduleTriggerId, type: 'schedule' as const, cronExpression: '0 9 * * *', timezone: 'Europe/Brussels', humanReadable: 'Daily at 9:00 AM Brussels time', title: 'Scheduled Report', description: 'Automatic daily pipeline report', } satisfies ScheduleTrigger, ], outputSchema: getOutputSchema(), // ... }, ]; ``` ### Manual trigger input The HTTP trigger accepts optional parameters: ```typescript theme={null} function getManualTriggerInputSchema(): FormInputSchema { return [ { type: 'section', title: 'Report Options', collapsible: true, inputSchema: [ { key: 'include_lead_names', type: 'boolean', label: 'Include Lead Names', description: 'Show individual lead names in the report', defaultValue: false, }, { key: 'custom_message', type: 'text', label: 'Custom Note', description: 'Optional message to include in the Slack post', maxLength: 500, }, ], }, ]; } ``` ### Rich deployment parameters ```typescript theme={null} export function getDeploymentInputSchema(): DeploymentInputSchema { return [ { key: 'FOLK_GROUP_ID', type: 'string', label: 'Folk Group ID', description: 'The ID of the Folk CRM group (pipeline) to analyze', required: true, }, { key: 'FOLK_GROUP_NAME', type: 'string', label: 'Group Display Name', description: 'Name shown in the Slack report header', required: true, defaultValue: 'Sales Pipeline', }, { key: 'SLACK_CHANNEL_ID', type: 'string', label: 'Slack Channel', description: 'Channel ID where the report is posted', required: true, placeholder: 'C01234ABCDE', }, { key: 'SCHEDULE_FREQUENCY', type: 'select', label: 'Report Frequency', description: 'How often to generate the automated report', required: true, defaultValue: 'daily', options: [ { value: 'daily', label: 'Daily' }, { value: 'weekly', label: 'Weekly (Monday)' }, { value: 'biweekly', label: 'Bi-weekly' }, { value: 'monthly', label: 'Monthly' }, ], }, { key: 'STATUS_FIELD_NAME', type: 'string', label: 'Status Field Name', description: 'Custom field name for pipeline status (if renamed in Folk)', required: false, defaultValue: 'Status', }, ]; } ``` ### Organization-level credentials Folk CRM and Slack are shared across the organization: ```typescript theme={null} integrationUids: ['folk', 'slack'], ``` ```json theme={null} "credentials": { "folkApi": { "id": "{{ORGCRED_FOLK_ID_DERCGRO}}", "name": "{{ORGCRED_FOLK_NAME_DERCGRO}}" } } ``` ## Workflow pattern ``` Schedule Trigger ──┐ ├──→ Codika Init → Process Input → Get Folk Data → Calculate Stats Manual Webhook ────┘ ↓ Post to Slack ↓ IF Success ├── Submit Result └── Report Error ``` ### Dual trigger convergence Both triggers feed into the same Codika Init node. The CLI validates this via the `CK-SCHEDULE-CONVERGENCE` rule. ### Codika Init handles both modes: * **HTTP trigger**: Extracts execution metadata from webhook * **Schedule trigger**: Creates execution via API call A Code node after Init detects which trigger fired and normalizes the input: ```javascript theme={null} const webhookData = $('Webhook Trigger').first(); const scheduleData = $('Schedule Trigger').first(); // Determine trigger source const isManual = webhookData?.json?.body?.payload !== undefined; const includeNames = isManual ? webhookData.json.body.payload.include_lead_names : false; ``` ## Output schema ```typescript theme={null} function getOutputSchema(): FormOutputSchema { return [ { key: 'total_leads', type: 'number', label: 'Total Leads', numberType: 'integer' }, { key: 'columns_analyzed', type: 'number', label: 'Columns Analyzed', numberType: 'integer' }, { key: 'new_leads_count', type: 'number', label: 'New Leads', numberType: 'integer' }, { key: 'followup_count', type: 'number', label: 'Follow-ups Needed', numberType: 'integer' }, { key: 'slack_message_ts', type: 'string', label: 'Slack Message ID' }, ]; } ``` ## Key patterns demonstrated 1. **Dual triggers** — schedule for automation + HTTP for manual override 2. **ORGCRED** — organization-level credentials (shared Folk CRM and Slack) 3. **Select deployment parameter** — dropdown for report frequency 4. **Trigger detection** — Code node determines which trigger fired 5. **External API calls** — HTTP requests to Folk CRM API 6. **Slack posting** — Send formatted messages with Block Kit # Simple Web Search Source: https://doc.codika.io/examples/simple-search Minimal use case — a single HTTP-triggered workflow that searches the web via Tavily and returns formatted results ## Overview | Property | Value | | --------------- | ----------------- | | Workflows | 1 | | Trigger | HTTP (webhook) | | Integrations | Tavily | | Credential type | FLEXCRED (Tavily) | | Cost | 1 credit | | Complexity | Minimal | This is the simplest possible Codika use case: one workflow, one trigger, one API call. ## Folder structure ``` tavily-search/ config.ts version.json project.json workflows/ tavily-search.json ``` ## config.ts ```typescript theme={null} import { loadAndEncodeWorkflow, type ProcessDeploymentConfigurationInput, type FormInputSchema, type FormOutputSchema } from 'codika'; import { fileURLToPath } from 'url'; import { dirname } from 'path'; import crypto from 'crypto'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); export const WORKFLOW_FILES = ['workflows/tavily-search.json']; export function getConfiguration(): ProcessDeploymentConfigurationInput { const webhookId = crypto.randomUUID(); const webhookUrl = `{{ORGSECRET_N8N_BASE_URL_TERCESORG}}/webhook/{{PROCDATA_PROCESS_ID_ATADCORP}}/{{USERDATA_PROCESS_INSTANCE_UID_ATADRESU}}/search`; return { title: 'Tavily Web Search', subtitle: 'Quick web search results', description: 'Search the web and get formatted results using the Tavily API.', workflows: [ { workflowTemplateId: 'tavily-search', workflowId: 'tavily-search', workflowName: 'Tavily Web Search', integrationUids: ['tavily'], triggers: [ { triggerId: webhookId, type: 'http' as const, url: webhookUrl, method: 'POST' as const, title: 'Search the Web', description: 'Enter a query to search the web', inputSchema: getInputSchema(), }, ], outputSchema: getOutputSchema(), n8nWorkflowJsonBase64: loadAndEncodeWorkflow(__dirname, 'workflows/tavily-search.json'), cost: 1, }, ], tags: ['search', 'web', 'tavily'], }; } function getInputSchema(): FormInputSchema { return [ { type: 'section', title: 'Search Query', collapsible: false, inputSchema: [ { key: 'query', type: 'text', label: 'Search Query', description: 'What do you want to search for?', placeholder: 'Enter your search query...', required: true, maxLength: 1000, }, ], }, ]; } function getOutputSchema(): FormOutputSchema { return [ { key: 'results', type: 'text', label: 'Search Results', description: 'Formatted search results from the web', }, ]; } ``` ## Workflow pattern ``` Webhook (POST) → Codika Init → Tavily API Call → Format Results → IF Success ├── Yes → Submit Result └── No → Report Error ``` ## Key details ### Input Single text field for the search query. Accessed in the workflow via: ```javascript theme={null} $('Webhook Trigger').first().json.body.payload.query ``` ### Credentials Uses FLEXCRED for Tavily — the platform automatically provides API credentials (org-owned or Codika-provided): ```json theme={null} "credentials": { "tavilyApi": { "id": "{{FLEXCRED_TAVILY_ID_DERCXELF}}", "name": "{{FLEXCRED_TAVILY_NAME_DERCXELF}}" } } ``` ### Output Returns a single text field with formatted search results. ## Deploy and test ```bash theme={null} cd tavily-search codika verify use-case . codika deploy use-case . codika trigger tavily-search --poll --payload-file - <<'EOF' {"query": "latest AI news"} EOF ``` # Creating Agent Skills Source: https://doc.codika.io/guides/agent-skills Step-by-step guide to creating skills that make your use case workflows accessible to AI agents ## Overview This guide walks you through adding agent skills to an existing use case. By the end, your HTTP endpoints and scheduled workflows will be discoverable and usable by any Claude-based agent. **New use cases get skills automatically.** When you run `codika init`, the scaffolded use case includes example skills for both the HTTP workflow and the scheduled workflow. This guide is for adding skills to existing use cases or customizing the defaults. **Prefer automation?** The [Builder System](/builder/overview) agents create use cases with correctly configured agent skills out of the box. Use this guide when you need to add or customize skills manually. ## Step 1: Identify triggerable workflows Open your `config.ts` and list all workflows with `http` or `schedule` trigger types. Skip sub-workflows, data ingestion, and service event workflows. ```bash theme={null} # Quick check — list workflow files that are NOT sub-workflows grep -l '"type": "n8n-nodes-base.webhook"' workflows/*.json grep -l '"type": "n8n-nodes-base.scheduleTrigger"' workflows/*.json ``` For each triggerable workflow, note: * `workflowTemplateId` from config.ts * Trigger type (http or schedule) * Input schema fields (for HTTP) * Output schema fields * Integration UIDs used * Credit cost ## Step 2: Create the skills directory ```bash theme={null} mkdir -p skills ``` For each triggerable workflow, create a subdirectory: ```bash theme={null} mkdir skills/main-workflow mkdir skills/scheduled-report ``` ## Step 3: Write SKILL.md files ### For HTTP workflows Create `skills/{name}/SKILL.md`: ```markdown theme={null} --- name: {usecase-slug}-{action} description: {Third-person description. What it does and what it returns.} workflowTemplateId: {workflow-template-id} --- # {Workflow Name} {One-line description with integrations used.} ## How to trigger \`\`\`bash codika trigger {workflow-template-id} --payload-file - <<'EOF' { "field1": "example value", "field2": 42 } EOF \`\`\` ## Input | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | field1 | string | yes | What this field does | | field2 | number | no | What this field does | ## Output \`\`\`json { "result": "example output", "timestamp": "2025-01-01T00:00:00.000Z" } \`\`\` ## Notes - Cost: {N} credit(s) - Uses: {Integration1}, {Integration2} ``` ### For scheduled workflows ```markdown theme={null} --- name: {usecase-slug}-{action} description: {Third-person description. Mention the schedule AND manual trigger.} workflowTemplateId: {workflow-template-id} --- # {Workflow Name} Runs automatically on a schedule ({schedule description}). ## Schedule `{cron expression}` — {Human-readable} ({timezone}) ## Manual trigger (for testing) \`\`\`bash codika trigger {workflow-template-id} \`\`\` No payload required. ## Output | Field | Type | Description | |-------|------|-------------| | field1 | string | Description | ## Notes - Cost: {N} credit(s) - Uses: {Integration1}, {Integration2} ``` ## Step 4: Validate ```bash theme={null} codika verify use-case . ``` Check for skill-related findings: * `SKILL-STRUCTURE` — Missing SKILL.md in a skills subdirectory * `SKILL-NAME-FORMAT` — Name too long, wrong characters, or reserved words * `SKILL-WORKFLOW-REF` — workflowTemplateId doesn't match any workflow * `SKILL-DUPLICATE` — Duplicate names or workflowTemplateIds ## Step 5: Deploy ```bash theme={null} codika deploy use-case . ``` Skills are automatically collected and sent with the deployment. No config.ts changes needed. ## Step 6: Verify agent access ```bash theme={null} # Download the skills you just deployed codika get skills # Or check the JSON output codika get skills --json ``` You should see all your skills listed with their names, descriptions, and content. ## Naming rules The `name` field must follow Claude's naming constraints: | Rule | Example | | ---------------------------------------- | --------------------------------------- | | Max 64 characters | `wat-event-weekly-digest` (24 chars) | | Lowercase letters, numbers, hyphens only | `propale-generate-proposal` | | No spaces or underscores | `my-skill` not `my_skill` or `my skill` | | No reserved words | Cannot contain "anthropic" or "claude" | **Convention:** Prefix with your use case slug: `wat-`, `propale-`, `crm-`. ## Description rules | Rule | Good | Bad | | --------------------- | ----------------------------------------------------------- | ----------------------- | | Third person | "Sends a message to..." | "Use this to send..." | | Non-empty | "Generates a weekly digest" | "" | | Max 1024 characters | Keep it concise | Don't write a paragraph | | Include what AND when | "Sends reminders daily at 8 AM. Can be manually triggered." | "Sends reminders" | ## Progressive disclosure for complex skills If a skill needs more than 500 lines, split into referenced files: ``` generate-proposal/ ├── SKILL.md # Overview + trigger command + basic I/O ├── INPUT-REFERENCE.md # Detailed field-by-field input schema └── EXAMPLES.md # Multiple usage examples with different payloads ``` Reference them from SKILL.md: ```markdown theme={null} For detailed input schema, see [INPUT-REFERENCE.md](INPUT-REFERENCE.md). For more examples, see [EXAMPLES.md](EXAMPLES.md). ``` Claude reads SKILL.md first, then loads referenced files only when needed. ## Checklist Before deploying: * [ ] One skill per triggerable workflow (HTTP + scheduled with manual trigger) * [ ] No skills for sub-workflows or data ingestion * [ ] Each skill is a `{name}/SKILL.md` directory * [ ] Frontmatter has `name`, `description`, `workflowTemplateId` * [ ] `name` is valid (lowercase, hyphens, max 64 chars, no reserved words) * [ ] `description` is third person and under 1024 chars * [ ] `workflowTemplateId` matches a workflow in config.ts * [ ] Body includes `codika trigger` command with example payload * [ ] Body includes input/output schemas * [ ] `codika verify use-case .` passes # AI Workflows Source: https://doc.codika.io/guides/ai-workflows Build workflows that use Claude and other LLMs for classification, extraction, and generation using n8n LangChain nodes ## Overview Codika workflows use n8n's LangChain integration nodes to run AI operations. The two main node types for LLM processing are: | Node | Use when | Why | | ---------- | ---------------------------------------------------- | ----------------------------------- | | `chainLlm` | Structured output (classification, extraction, JSON) | Direct response, no reasoning noise | | `agent` | Multi-step reasoning, tool usage | Planning and iteration capability | **Critical rule:** Use `chainLlm` when you need structured JSON output. The `agent` node adds verbose reasoning before the final answer, which breaks structured output parsers. ## Architecture Both node types follow the same wiring pattern: ``` lmChatAnthropic (model + credentials) ──ai_languageModel──┐ ├──→ chainLlm or agent outputParserStructured ────────────ai_outputParser─────────┘ ``` **Credentials go on the model node**, not on the chain/agent node. ## Basic chainLlm example This classifies an email as "newsletter", "action\_item", or "spam": ### LLM Model node ```json theme={null} { "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic", "typeVersion": 1.3, "position": [600, 500], "id": "model-1", "name": "Claude Model", "parameters": { "model": { "__rl": true, "value": "claude-haiku-4-5-20251001", "mode": "list" }, "options": { "maxTokensToSample": 1024, "temperature": 0.3 } }, "credentials": { "anthropicApi": { "id": "{{FLEXCRED_ANTHROPIC_ID_DERCXELF}}", "name": "{{FLEXCRED_ANTHROPIC_NAME_DERCXELF}}" } } } ``` ### Output Parser node ```json theme={null} { "type": "@n8n/n8n-nodes-langchain.outputParserStructured", "typeVersion": 1.3, "position": [600, 600], "id": "parser-1", "name": "Classification Parser", "parameters": { "jsonSchemaExample": "{\"category\": \"newsletter\", \"confidence\": \"high\", \"reason\": \"Contains subscription links\"}" } } ``` ### Chain LLM node ```json theme={null} { "type": "@n8n/n8n-nodes-langchain.chainLlm", "typeVersion": 1.7, "position": [800, 400], "id": "chain-1", "name": "Classify Email", "parameters": { "promptType": "define", "text": "Classify the following email into one of these categories: newsletter, action_item, spam.\n\nEmail subject: {{ $json.subject }}\nEmail body: {{ $json.body }}\n\nRespond with the category, confidence (high/medium/low), and a brief reason.", "hasOutputParser": true } } ``` ### Connections ```json theme={null} { "Claude Model": { "ai_languageModel": [[{ "node": "Classify Email", "type": "ai_languageModel", "index": 0 }]] }, "Classification Parser": { "ai_outputParser": [[{ "node": "Classify Email", "type": "ai_outputParser", "index": 0 }]] } } ``` ## Accessing LLM output After the chainLlm node executes, the parsed output is available at: ```javascript theme={null} // In a Code node after chainLlm const result = $('Classify Email').first().json; const category = result.output.category; const confidence = result.output.confidence; ``` For `outputParserStructured`, the parsed JSON is in the `output` field of the chain's result. ## Available Claude models | Model | ID | Best for | | ----------------- | ---------------------------- | -------------------------------------- | | Claude Haiku 4.5 | `claude-haiku-4-5-20251001` | Fast classification, simple extraction | | Claude Sonnet 4.6 | `claude-sonnet-4-6-20250514` | Complex analysis, generation | | Claude Opus 4.6 | `claude-opus-4-6-20250527` | Most capable, multi-step reasoning | Use FLEXCRED placeholders for AI provider credentials — they automatically handle org-owned vs. Codika-provided API keys. ## Multi-step processing pattern For workflows that need to process multiple items (e.g., classify each email in a batch): ``` Fetch Items → Loop Over Items → chainLlm (classify each) → Aggregate → Submit Result ``` Use n8n's `SplitInBatches` or `Loop Over Items` node to iterate, with the chainLlm inside the loop. ## Temperature guidelines | Task | Temperature | Why | | -------------- | ----------- | --------------------------------- | | Classification | 0.0 - 0.3 | Deterministic, consistent results | | Extraction | 0.0 - 0.2 | Accurate data extraction | | Summarization | 0.3 - 0.5 | Some creative flexibility | | Generation | 0.5 - 0.8 | Creative, varied output | ## Common mistakes 1. **Credentials on chainLlm instead of lmChatAnthropic** — credentials must be on the model node 2. **Using `agent` for JSON output** — agent adds reasoning text that breaks structured parsers 3. **Missing `hasOutputParser: true`** on chainLlm — required when using outputParserStructured 4. **Accessing output incorrectly** — use `$('Node Name').first().json.output`, not `.json` directly # Codika Agent Plugin Source: https://doc.codika.io/guides/claude-code-plugin Install the Codika plugin in Claude Code, Cursor, or any Open-Plugin-compatible agent — deploy, test, and manage use cases directly from your terminal ## Overview The `codika` plugin gives AI coding agents direct access to the Codika platform. Once installed, your agent can scaffold use cases, validate workflows, deploy to production, trigger executions, debug failures, and autonomously build entire use cases from your business requirements. It ships as a single [Open Plugin v1](https://github.com/vercel-labs/open-plugin-spec)-conformant repo at [`codika-io/plugin`](https://github.com/codika-io/plugin), so you install it once and the CLI wires it into every compatible host (Claude Code, Cursor, …). | Component | What it adds | | --------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | **Skills (25)** | `/codika:*` commands that wrap the `codika` CLI — deploy, verify, trigger, fetch, manage integrations, and more | | **Agents (4)** | Autonomous agents that design, build, modify, and test use cases. Invoked via the Task tool with `subagent_type: "codika:"` | ## Prerequisites * A supported agent host (Claude Code, Cursor, …) installed and running * Node.js 22+ * The `codika` CLI installed (`npm install -g codika`) * A Codika API key (from the dashboard under **Organization Settings > API Keys**) If you haven't set up the CLI yet, the agent will guide you through it automatically using the `/codika:setup-codika` skill after installing the plugin. ## Install ### Add the plugin The simplest path — one command, works everywhere: ```bash theme={null} npx plugins add codika-io/plugin ``` The `plugins` CLI auto-detects which agent tools are installed on your machine (Claude Code, Cursor, …) and installs into all of them. **Claude Code native alternative.** If you prefer Claude Code's built-in marketplace flow, run: ``` /plugin marketplace add codika-io/plugin /plugin install codika@plugin ``` Both paths produce the same `/codika:*` skills and agents. ### Verify the installation Ask your agent: ``` Which skills and agents do you have access to? ``` You should see skills prefixed with `codika:` (e.g., `codika:deploy-use-case`, `codika:trigger-workflow`) and the builder agents (`codika:use-case-builder`, `codika:use-case-modifier`, `codika:n8n-workflow-builder`, `codika:use-case-tester`). In Claude Code you can reload plugins at any time with: ``` /reload-plugins ``` ## Authenticate Before using any platform operations, authenticate the CLI: ```bash theme={null} codika login ``` Or pass the key directly: ```bash theme={null} codika login --api-key cko_your_api_key_here ``` Verify with: ```bash theme={null} codika whoami ``` If you skip this step, the agent will prompt you to authenticate the first time a command fails. ## What you can do ### CLI skills Ask your agent naturally — it picks the right skill automatically. | Ask the agent to... | Skill used | | -------------------------------- | ---------------------------- | | "Scaffold a new use case" | `codika:init-use-case` | | "Validate my use case" | `codika:verify-use-case` | | "Deploy this use case" | `codika:deploy-use-case` | | "Trigger the main workflow" | `codika:trigger-workflow` | | "Show me the last execution" | `codika:get-execution` | | "List recent executions" | `codika:list-executions` | | "Publish to production" | `codika:publish-use-case` | | "Download the deployed use case" | `codika:fetch-use-case` | | "Set up the Slack integration" | `codika:manage-integrations` | ### Builder agents For more complex tasks, the agent delegates to specialized sub-agents (invoked via Task tool with `subagent_type: "codika:"`): | Ask the agent to... | Sub-agent used | | ----------------------------------------------------- | ----------------------------- | | "Build a use case that processes invoices from email" | `codika:use-case-builder` | | "Add Slack notifications to this use case" | `codika:use-case-modifier` | | "Build a workflow that calls the Tavily API" | `codika:n8n-workflow-builder` | | "Deploy and test this use case, fix any issues" | `codika:use-case-tester` | The builder agents read Codika's platform documentation at runtime (bundled inside the `codika:discover-codika-guides` skill), so they always follow current patterns for triggers, placeholders, credentials, and mandatory nodes. ## Example session ``` You: Build a use case that monitors Gmail for invoices, extracts data with Claude, and saves results to Google Sheets Agent: I'll use the use-case-builder agent to design and create this. [reads platform docs via codika:discover-codika-guides] [designs architecture] [creates config.ts with Gmail trigger, FLEXCRED_ANTHROPIC, USERCRED_GOOGLE] [builds 2 workflows: gmail-trigger.json + invoice-parser.json (sub-workflow)] [runs codika verify to validate] ✓ Use case created at ./invoice-processor/ Want me to deploy and test it? You: Yes, deploy and test it Agent: [deploys via codika:deploy-use-case] [triggers via codika:trigger-workflow] [inspects execution via codika:get-execution] ✓ Deployed and tested successfully Version: 1.0.1 | Instance: abc123 ``` ## Updating To get the latest skills and agents: ```bash theme={null} npx plugins add codika-io/plugin ``` Re-running `plugins add` on the same repo pulls the latest version. In Claude Code native: ``` /plugin update codika@plugin ``` ## Uninstalling ``` /plugin uninstall codika@plugin ``` To remove the marketplace entry in Claude Code native: ``` /plugin marketplace remove plugin ``` ## Troubleshooting In Claude Code, run `/reload-plugins` to force a rediscovery. You should see a count of plugins, skills, and agents in the output. Other hosts usually refresh on the next session restart. Run `codika login` followed by `codika whoami` to verify your credentials. If using multiple organizations, make sure the correct profile is active. The `codika:discover-codika-guides` skill must be available. Verify the `codika` plugin is installed by asking your agent "which skills do you have?". You should see `codika:discover-codika-guides` in the list. Make sure the `codika` CLI is installed globally (`npm install -g codika`). The skills shell out to the CLI — without it, none of the platform operations work. ## Next steps Install the CLI and deploy your first use case. Deep dive into the autonomous builder agents. Complete reference for all codika CLI commands. Make your workflows discoverable by AI agents. # Deployment Parameters Source: https://doc.codika.io/guides/deployment-parameters Define user-configurable values that are set at process installation time and injected into workflows via INSTPARM placeholders ## What are deployment parameters? Deployment parameters are values that users configure **once** when they install a process. Unlike trigger inputs (which change per execution), deployment parameters are baked into the workflow at deployment time. Examples: * Company name to include in reports * Slack channel ID to post notifications to * Maximum number of items to process * API endpoint URLs for external services ## How it works ``` config.ts: getDeploymentInputSchema() → User fills form at install time → Values stored with the user's process instance → INSTPARM placeholders replaced in workflows ``` ## Defining parameters in config.ts ### getDeploymentInputSchema() ```typescript theme={null} export function getDeploymentInputSchema(): DeploymentInputSchema { return [ { key: 'COMPANY_NAME', type: 'string', label: 'Company Name', description: 'Your company name, used in generated reports', placeholder: 'Acme Corp', required: true, }, { key: 'SLACK_CHANNEL_ID', type: 'string', label: 'Slack Channel', description: 'Channel ID where notifications will be posted', placeholder: 'C01234ABCDE', required: true, }, { key: 'MAX_ITEMS', type: 'number', label: 'Maximum Items', description: 'Maximum number of items to process per execution', required: false, defaultValue: 50, min: 1, max: 500, }, { key: 'REPORT_FREQUENCY', type: 'select', label: 'Report Frequency', required: true, defaultValue: 'daily', options: [ { value: 'daily', label: 'Daily' }, { value: 'weekly', label: 'Weekly' }, { value: 'biweekly', label: 'Bi-weekly' }, { value: 'monthly', label: 'Monthly' }, ], }, { key: 'ENABLE_NOTIFICATIONS', type: 'boolean', label: 'Enable Notifications', description: 'Send Slack notification after each execution', defaultValue: true, }, ]; } ``` ### getDefaultDeploymentParameters() Provides default values for automated installations (no user interaction): ```typescript theme={null} export function getDefaultDeploymentParameters(): DeploymentParameterValues { return { COMPANY_NAME: 'My Company', SLACK_CHANNEL_ID: '', MAX_ITEMS: 50, REPORT_FREQUENCY: 'daily', ENABLE_NOTIFICATIONS: true, }; } ``` ## Using INSTPARM in workflows ### In Code nodes INSTPARM placeholders are context-aware — they serialize correctly based on the value type. **Do not add extra quotes.** ```javascript theme={null} // In a Code node const companyName = {{INSTPARM_COMPANY_NAME_MRAPTSNI}}; // String → "Acme Corp" const maxItems = {{INSTPARM_MAX_ITEMS_MRAPTSNI}}; // Number → 50 const enableNotifications = {{INSTPARM_ENABLE_NOTIFICATIONS_MRAPTSNI}}; // Boolean → true const frequency = {{INSTPARM_REPORT_FREQUENCY_MRAPTSNI}}; // String → "daily" ``` At deployment time, these become: ```javascript theme={null} const companyName = "Acme Corp"; const maxItems = 50; const enableNotifications = true; const frequency = "daily"; ``` ### In node parameters (expressions) ```json theme={null} { "parameters": { "channel": "{{INSTPARM_SLACK_CHANNEL_ID_MRAPTSNI}}" } } ``` ### In HTTP request bodies ```json theme={null} { "parameters": { "jsonBody": "={{ JSON.stringify({ company: {{INSTPARM_COMPANY_NAME_MRAPTSNI}}, limit: {{INSTPARM_MAX_ITEMS_MRAPTSNI}} }) }}" } } ``` ## Field types All 11 field types from the [Input Schema reference](/concepts/schemas) are available: | Type | INSTPARM serialization | | ------------- | ----------------------------------- | | `string` | `"value"` (quoted) | | `text` | `"value"` (quoted) | | `number` | `42` (unquoted) | | `boolean` | `true` or `false` (unquoted) | | `select` | `"selected_value"` (quoted) | | `multiselect` | `["val1", "val2"]` (JSON array) | | `array` | `["item1", "item2"]` (JSON array) | | `object` | `{"key": "value"}` (JSON object) | | `date` | `"2026-01-15"` (ISO string, quoted) | ## Validation The CLI checks INSTPARM usage via: | Rule | What it checks | | --------------------- | --------------------------------------------------------------------------------- | | `WF-INSTPARM-QUOTING` | INSTPARM placeholders are not double-quoted (e.g., `"{{INSTPARM_...}}"` is wrong) | | `CK-PLACEHOLDERS` | Placeholder syntax is correct | ## Version updates When a process is updated to a new version, existing deployment parameters are **preserved**. New parameters use their default values. Removed parameters are ignored. # File Uploads Source: https://doc.codika.io/guides/file-uploads Generate and upload files (PDFs, images, videos) from workflows and return them as output to users ## Overview Workflows can generate files and upload them to Codika's storage using the Codika Upload File node. The uploaded file gets a `documentId` that can be included in the workflow's output as a `file` type field. ## Pattern ``` Generate/Download File → Codika Upload File → Code Node (extract documentId) → Codika Submit Result ``` ## Step 1: Generate or download the file Use any n8n node that produces binary data: ```json theme={null} { "type": "n8n-nodes-base.httpRequest", "parameters": { "url": "https://api.example.com/generate-pdf", "responseFormat": "file" }, "name": "Generate PDF" } ``` ## Step 2: Upload with Codika Upload File ```json theme={null} { "type": "n8n-nodes-codika.codika", "typeVersion": 1, "parameters": { "resource": "fileManagement", "operation": "uploadFile" }, "name": "Upload File" } ``` The node uploads the binary data from the previous node and returns a `documentId`. ## Step 3: Return the documentId in output In a Code node before Codika Submit Result: ```javascript theme={null} const documentId = $('Upload File').first().json.documentId; return [{ json: { results: { generated_report: documentId, summary: 'Report generated successfully', } } }]; ``` ## Step 4: Define file type in output schema In `config.ts`: ```typescript theme={null} function getOutputSchema(): FormOutputSchema { return [ { key: 'generated_report', type: 'file', label: 'Generated Report', description: 'PDF report generated by the workflow', }, { key: 'summary', type: 'string', label: 'Summary', description: 'Brief summary of the report', }, ]; } ``` ## File uploads in sub-workflows Sub-workflows do not have their own Codika Init node, so the Upload File node needs explicit execution metadata. The parent must forward `executionId` and `executionSecret`. ### Parent workflow passes metadata ```json theme={null} { "type": "n8n-nodes-base.executeWorkflow", "parameters": { "workflowId": { "__rl": true, "mode": "id", "value": "{{SUBWKFL_pdf-generator_LFKWBUS}}" }, "workflowInputs": { "mappingMode": "defineBelow", "value": { "markdownContent": "={{ $json.markdown }}", "fileName": "report.pdf", "executionId": "={{ $('Codika Init').first().json.executionId }}", "executionSecret": "={{ $('Codika Init').first().json.executionSecret }}" } } } } ``` ### Sub-workflow uses overrides ```json theme={null} { "type": "n8n-nodes-codika.codika", "parameters": { "resource": "fileManagement", "operation": "uploadFile", "executionIdOverride": "={{ $('When Called by Parent').first().json.executionId }}", "executionSecretOverride": "={{ $('When Called by Parent').first().json.executionSecret }}" }, "name": "Upload File" } ``` ### Sub-workflow input schema in config.ts ```typescript theme={null} { type: 'subworkflow' as const, inputSchema: [ { key: 'markdownContent', type: 'string' }, { key: 'fileName', type: 'string' }, { key: 'executionId', type: 'string' }, { key: 'executionSecret', type: 'string' }, ], calledBy: ['main-workflow'], } ``` ## File input (user uploads) Users can upload files via the input schema: ```typescript theme={null} { key: 'document', type: 'file', label: 'Upload Document', required: true, maxSize: 50 * 1024 * 1024, allowedMimeTypes: ['application/pdf', '.docx', '.doc', '.txt'], } ``` The file data arrives in the webhook payload and can be accessed in workflow nodes. ## Supported file types for upload The Codika Upload File node supports: | Category | Types | | --------- | --------------------------------------------- | | Documents | PDF, Word (.docx), Excel (.xlsx), Text (.txt) | | Images | PNG, JPG, GIF, SVG, WEBP | | Archives | ZIP, TAR, TAR.GZ | | Media | Video (various formats) | | Data | JSON, YAML, CSV | # Build Your First Use Case Source: https://doc.codika.io/guides/first-use-case Step-by-step guide to creating a complete use case from scratch — from an empty folder to a deployed, triggerable automation ## What you'll build A web search tool that takes a query via HTTP, searches the web using Tavily, and returns formatted results. This is a minimal but complete use case that demonstrates the full lifecycle. ## Prerequisites * `codika` CLI installed and authenticated (see [Quickstart](/quickstart)) * A Codika API key with `deploy:use-case` and `workflows:trigger` scopes ## Step 1: Create the project ```bash theme={null} mkdir web-search && cd web-search codika project create --name "Web Search Tool" --path . ``` This creates `project.json` with your `projectId` and `organizationId`. ## Step 2: Create version.json ```json version.json theme={null} { "version": "1.0.0" } ``` ## Step 3: Create config.ts ```typescript config.ts theme={null} import { loadAndEncodeWorkflow, type ProcessDeploymentConfigurationInput, type FormInputSchema, type FormOutputSchema } from 'codika'; import { fileURLToPath } from 'url'; import { dirname } from 'path'; import crypto from 'crypto'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); export const WORKFLOW_FILES = [ 'workflows/web-search.json', ]; export function getConfiguration(): ProcessDeploymentConfigurationInput { const webhookId = crypto.randomUUID(); const webhookUrl = `{{ORGSECRET_N8N_BASE_URL_TERCESORG}}/webhook/{{PROCDATA_PROCESS_ID_ATADCORP}}/{{USERDATA_PROCESS_INSTANCE_UID_ATADRESU}}/search`; return { title: 'Web Search Tool', subtitle: 'AI-powered web search', description: 'Search the web and get formatted results using Tavily.', workflows: [ { workflowTemplateId: 'web-search', workflowId: 'web-search', workflowName: 'Web Search', integrationUids: ['tavily'], triggers: [ { triggerId: webhookId, type: 'http' as const, url: webhookUrl, method: 'POST' as const, title: 'Search the Web', description: 'Enter a query to search the web', inputSchema: getInputSchema(), }, ], outputSchema: getOutputSchema(), n8nWorkflowJsonBase64: loadAndEncodeWorkflow(__dirname, 'workflows/web-search.json'), cost: 1, }, ], tags: ['search', 'web'], }; } function getInputSchema(): FormInputSchema { return [ { type: 'section', title: 'Search', collapsible: false, inputSchema: [ { key: 'query', type: 'text', label: 'Search Query', description: 'What to search for on the web', placeholder: 'Enter your search query...', required: true, maxLength: 1000, }, ], }, ]; } function getOutputSchema(): FormOutputSchema { return [ { key: 'results', type: 'text', label: 'Search Results', description: 'Formatted search results from the web', }, ]; } ``` ## Step 4: Create the workflow Create the `workflows/` directory and the workflow JSON: ```json workflows/web-search.json theme={null} { "name": "Web Search", "nodes": [ { "parameters": { "httpMethod": "POST", "path": "{{PROCDATA_PROCESS_ID_ATADCORP}}/{{USERDATA_PROCESS_INSTANCE_UID_ATADRESU}}/search", "responseMode": "lastNode", "options": {} }, "type": "n8n-nodes-base.webhook", "typeVersion": 2, "position": [200, 300], "id": "webhook-1", "name": "Webhook Trigger", "webhookId": "{{USERDATA_PROCESS_INSTANCE_UID_ATADRESU}}" }, { "parameters": { "resource": "processManagement", "operation": "initWorkflow" }, "type": "n8n-nodes-codika.codika", "typeVersion": 1, "position": [400, 300], "id": "init-1", "name": "Codika Init" }, { "parameters": { "url": "=https://api.tavily.com/search", "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify({ query: $('Webhook Trigger').first().json.body.payload.query, max_results: 5 }) }}", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [600, 300], "id": "search-1", "name": "Tavily Search", "credentials": { "tavilyApi": { "id": "{{FLEXCRED_TAVILY_ID_DERCXELF}}", "name": "{{FLEXCRED_TAVILY_NAME_DERCXELF}}" } } }, { "parameters": { "jsCode": "const results = $input.first().json.results || [];\nconst formatted = results.map((r, i) => `${i+1}. **${r.title}**\\n ${r.url}\\n ${r.content}`).join('\\n\\n');\nreturn [{ json: { results: formatted || 'No results found.' } }];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [800, 300], "id": "format-1", "name": "Format Results" }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "" }, "conditions": [ { "leftValue": "={{ $json.results }}", "rightValue": "", "operator": { "type": "string", "operation": "exists" } } ] } }, "type": "n8n-nodes-base.if", "typeVersion": 2, "position": [1000, 300], "id": "if-1", "name": "IF Success" }, { "parameters": { "resource": "processManagement", "operation": "submitResult", "resultData": "={{ JSON.stringify({ results: $json.results }) }}" }, "type": "n8n-nodes-codika.codika", "typeVersion": 1, "position": [1200, 200], "id": "submit-1", "name": "Codika Submit Result" }, { "parameters": { "resource": "processManagement", "operation": "reportError", "errorMessage": "Search failed or returned no results", "errorType": "external_api_error" }, "type": "n8n-nodes-codika.codika", "typeVersion": 1, "position": [1200, 400], "id": "error-1", "name": "Codika Report Error" } ], "connections": { "Webhook Trigger": { "main": [[{ "node": "Codika Init", "type": "main", "index": 0 }]] }, "Codika Init": { "main": [[{ "node": "Tavily Search", "type": "main", "index": 0 }]] }, "Tavily Search": { "main": [[{ "node": "Format Results", "type": "main", "index": 0 }]] }, "Format Results": { "main": [[{ "node": "IF Success", "type": "main", "index": 0 }]] }, "IF Success": { "main": [ [{ "node": "Codika Submit Result", "type": "main", "index": 0 }], [{ "node": "Codika Report Error", "type": "main", "index": 0 }] ] } }, "settings": { "executionOrder": "v1", "errorWorkflow": "{{ORGSECRET_ERROR_WORKFLOW_ID_TERCESORG}}", "timezone": "Europe/Brussels" } } ``` ## Step 5: Validate ```bash theme={null} codika verify use-case . ``` Fix any issues: ```bash theme={null} codika verify use-case . --fix ``` ## Step 6: Deploy ```bash theme={null} codika deploy use-case . ``` ## Step 7: Test ```bash theme={null} codika trigger web-search --poll --payload-file - <<'EOF' {"query": "best practices for n8n workflows"} EOF ``` ## Final folder structure ``` web-search/ config.ts version.json project.json workflows/ web-search.json deployments/ # Created after deploy {projectId}/ project-info.json process/ 1.1/ deployment-info.json config-snapshot.json workflows/ web-search.json ``` ## Key takeaways 1. Every use case needs `config.ts`, `version.json`, and `workflows/` 2. The config exports `WORKFLOW_FILES` and `getConfiguration()` 3. Workflows follow the mandatory pattern: Trigger → Init → Logic → Submit/Error 4. Credentials use placeholders (`FLEXCRED`, `USERCRED`, etc.) 5. The CLI handles versioning, encoding, and API communication # Sub-Workflows Source: https://doc.codika.io/guides/sub-workflows Create helper workflows that are called by parent workflows — with proper parameter passing, SUBWKFL placeholders, and execution metadata forwarding ## What are sub-workflows? Sub-workflows are helper workflows called by parent workflows via n8n's Execute Workflow node. They encapsulate reusable logic (PDF generation, data parsing, API calls) and are invisible to end users. ## Key rules | Rule | Details | | ----------------------------------- | --------------------------------------------------------------- | | No Codika Init | Sub-workflows do not register their own execution | | No Submit Result / Report Error | Data returns to parent via Execute Workflow | | At least 1 input parameter | n8n requires this | | Cost: 0 | Execution cost attributed to parent | | Output schema: \[] | Always empty | | Start with Execute Workflow Trigger | Required entry point | | SUBWKFL placeholder | Parent references sub-workflow by placeholder, not hardcoded ID | ## config.ts definition ### Sub-workflow entry ```typescript theme={null} { workflowTemplateId: 'text-processor', workflowId: 'text-processor', workflowName: 'Text Processor', integrationUids: [], triggers: [ { triggerId: crypto.randomUUID(), type: 'subworkflow' as const, title: 'Process Text', description: 'Called by parent to process text chunks', inputSchema: [ { key: 'text', type: 'string' }, { key: 'maxLength', type: 'number' }, { key: 'executionId', type: 'string' }, { key: 'executionSecret', type: 'string' }, ], calledBy: ['main-workflow'], } satisfies SubworkflowTrigger, ], outputSchema: [], n8nWorkflowJsonBase64: loadAndEncodeWorkflow(__dirname, 'workflows/text-processor.json'), cost: 0, } ``` ### Parent workflow entry The parent workflow lists the sub-workflow's `integrationUids` in its own `integrationUids` array (integration inheritance). ## Sub-workflow JSON ### Entry node (Execute Workflow Trigger) ```json theme={null} { "type": "n8n-nodes-base.executeWorkflowTrigger", "typeVersion": 1.1, "position": [200, 300], "id": "trigger-1", "name": "When Called by Parent", "parameters": { "workflowInputs": { "values": [ { "name": "text", "type": "string" }, { "name": "maxLength", "type": "number" }, { "name": "executionId", "type": "string" }, { "name": "executionSecret", "type": "string" } ] } } } ``` ### Accessing input data ```javascript theme={null} // In a Code node inside the sub-workflow const text = $('When Called by Parent').first().json.text; const maxLength = $('When Called by Parent').first().json.maxLength; ``` ## Parent workflow: calling the sub-workflow ### Execute Workflow node ```json theme={null} { "type": "n8n-nodes-base.executeWorkflow", "typeVersion": 1.3, "position": [800, 300], "id": "exec-1", "name": "Call Text Processor", "parameters": { "workflowId": { "__rl": true, "mode": "id", "value": "{{SUBWKFL_text-processor_LFKWBUS}}" }, "workflowInputs": { "mappingMode": "defineBelow", "value": { "text": "={{ $json.input_text }}", "maxLength": 500, "executionId": "={{ $('Codika Init').first().json.executionId }}", "executionSecret": "={{ $('Codika Init').first().json.executionSecret }}" } }, "options": { "waitForSubWorkflow": true } } } ``` Key points: * `workflowId` uses the `SUBWKFL` placeholder with the sub-workflow's `workflowTemplateId` * `waitForSubWorkflow: true` makes the parent wait for the sub-workflow to complete * `executionId` and `executionSecret` are forwarded from Codika Init for platform tracking ## Passing execution metadata If the sub-workflow uses Codika Upload File, it needs the parent's execution metadata: ### Parent sends metadata ```json theme={null} "workflowInputs": { "value": { "data": "={{ $json.data }}", "executionId": "={{ $('Codika Init').first().json.executionId }}", "executionSecret": "={{ $('Codika Init').first().json.executionSecret }}" } } ``` ### Sub-workflow uses metadata in Upload File ```json theme={null} { "type": "n8n-nodes-codika.codika", "parameters": { "resource": "fileManagement", "operation": "uploadFile", "executionIdOverride": "={{ $('When Called by Parent').first().json.executionId }}", "executionSecretOverride": "={{ $('When Called by Parent').first().json.executionSecret }}" } } ``` ## SUBWKFL placeholder format ``` {{SUBWKFL__LFKWBUS}} ``` The `workflowTemplateId` in the placeholder must exactly match the `workflowTemplateId` in the config. Examples: * `{{SUBWKFL_text-processor_LFKWBUS}}` * `{{SUBWKFL_pdf-generator_LFKWBUS}}` * `{{SUBWKFL_email-parser_LFKWBUS}}` At deployment time, this is replaced with the actual n8n workflow ID. ## Deployment order Sub-workflows are deployed before parent workflows automatically. The platform resolves the dependency graph and deploys in the correct order. No manual ordering is needed. ## Validation The CLI checks sub-workflow patterns: | Rule | What it checks | | ----------------------- | ---------------------------------------------- | | `UC-SUBWORKFLOW-REFS` | SUBWKFL placeholders reference valid workflows | | `CK-SUBWORKFLOW-PARAMS` | Sub-workflows have at least 1 input parameter | | `UC-CALLEDBY` | calledBy arrays are consistent | # What is Codika? Source: https://doc.codika.io/index A multi-tenant SaaS platform for building, deploying, and managing n8n workflow automations with AI-powered orchestration ## Overview Codika is a platform that turns natural language descriptions into production-ready n8n workflow automations. It handles the full lifecycle: building workflows, deploying them to n8n, managing credentials, tracking executions, and distributing automations across organizations. The platform solves a specific problem: **n8n workflows are powerful but hard to productize**. Codika wraps n8n with multi-tenant deployment, credential isolation, version management, and a deployment pipeline that makes workflows installable and shareable. ## Built for humans AND agents Codika lets you build **dedicated APIs that contain the exact actions you want your agents to perform** — and completely decouples the authentication layer from agent usage. Agents get capabilities, not credentials. **How it works:** You build workflows that perform actions (search a CRM, generate a proposal, send a WhatsApp message). Codika deploys them as HTTP endpoints. You then create **agent skills** — documentation files that explain what each endpoint does, what input it expects, and what output it returns. Agents download these skills and know exactly how to use your APIs. **Why this matters:** Connecting agents to existing tools today means giving them OAuth tokens, API keys, and passwords — a security and operational nightmare. Codika inverts this. You connect your integrations once to the platform. The platform stores and manages all credentials. When an agent triggers a workflow, Codika injects the right credentials at runtime. The agent only ever holds a single Codika API key that grants access to the actions you've defined — nothing more. * **You define the agent's tool stack** — each workflow is an action, each skill documents it * **Agents call actions, not APIs** — `codika trigger send-message` instead of raw Twilio/Salesforce/Google calls * **One key to revoke** — disable the process instance and the agent loses access to everything, no credential rotation needed * **Same endpoints, two audiences** — the dashboard serves humans, the skills serve agents, the workflows power both ## What you can build A **use case** is Codika's fundamental deployment unit. It packages one or more n8n workflows with configuration, schemas, and metadata into a single deployable artifact. Examples of what use cases do: | Use Case | Trigger | What it does | | -------------------------- | ---------------------- | ----------------------------------------------------------------- | | Email attachment organizer | New email arrives | Saves attachments to Google Drive, logs to Sheets | | Daily inbox intelligence | Cron schedule (8 AM) | Categorizes unread emails with Claude, marks newsletters as read | | CRM funnel reporter | Schedule + manual HTTP | Pulls Folk CRM pipeline data, posts summary to Slack | | Proposal generator | User submits form | Searches similar docs via RAG, generates PDF proposal with Claude | | Web search tool | HTTP webhook | Runs Tavily search, returns formatted results | ## Architecture ``` User request (form, schedule, webhook, service event) → Codika platform (credential resolution, execution tracking) → n8n workflow (business logic, API calls, AI processing) → Results returned to user (structured output, files, notifications) ``` The system has three layers: | Layer | What it does | | ----------------------- | ----------------------------------------------------------------------------------------------------------------- | | **Codika Dashboard** | Web application where users manage organizations, projects, integrations, and processes. | | **codika CLI** | Command-line tool (`npm install -g codika`) for scaffolding, validating, and deploying use cases. | | **Codika Platform API** | Backend that handles deployment orchestration, credential resolution, version management, and workflow execution. | ## How deployment works ``` Use case folder (config.ts + workflows/*.json) → codika verify (validation) → codika deploy (packaging + API call) → Codika Platform (version management, deployment records) → n8n (placeholder replacement, credential injection, workflow creation) → Live automation (accessible via triggers) ``` When you deploy a use case: 1. The CLI validates the folder structure, config exports, and workflow patterns 2. Workflows are packaged and sent to the Codika platform API 3. The platform creates versioned deployment records and a process instance for the user 4. Workflows are deployed to n8n with all placeholders replaced with real values 5. The automation is live and can be triggered via HTTP, schedule, or service events ## Multi-tenancy model Every deployment is isolated per user. When a user installs a process, they get their own **process instance** with: * Isolated credentials (their own OAuth tokens, API keys) * Personal deployment parameters (configured at install time) * Independent execution tracking * Separate activation controls (pause, archive, reactivate) ``` Organization ├── Projects (scoped workspaces) ├── Integrations (OAuth connections: Gmail, Slack, Drive, etc.) ├── Members (roles: owner, member, viewer) └── Process Instances (deployed automations, one per user) ``` ## Key concepts | Concept | Definition | | -------------------- | ----------------------------------------------------------------------------------------------------------- | | **Use case** | A folder containing `config.ts` and `workflows/` that defines a deployable automation | | **Process** | The public, discoverable representation of a deployed use case | | **Process instance** | A user's personal installation of a process with isolated credentials and data | | **Placeholder** | A template token (e.g., `{{FLEXCRED_ANTHROPIC_ID_DERCXELF}}`) replaced at deployment with real values | | **Codika nodes** | Custom n8n nodes (Init, Submit Result, Report Error) that integrate workflows with the platform | | **Trigger** | How a workflow starts: HTTP webhook, cron schedule, service event, or sub-workflow call | | **Agent skill** | A Claude-compatible documentation file (`SKILL.md`) that describes how to interact with a deployed workflow | ## Next steps Understand why Codika exists and what it adds on top of n8n. Install the CLI and deploy your first use case in minutes. Add Codika skills and builder agents to Claude Code, Cursor, or any Open-Plugin-compatible agent. Understand how use cases are organized and configured. Full reference for all codika CLI commands. Real-world use case examples with complete code. Let AI agents create use cases from your business requirements. Make your workflows discoverable and usable by AI agents. Build a custom frontend on top of your deployed workflows. # Authentication Source: https://doc.codika.io/operations/authentication Install the codika CLI, authenticate with API keys, manage multiple profiles, and switch between organizations > **Agents / terminal-only setups:** if you have email access but no browser, use the [CLI OTP auth flow](./cli-auth) — two commands per signup or login, and a `cko_` key lands in `~/.config/codika/config.json` automatically. This page covers dashboard-paste login and profile management. ## When to use * First-time environment setup (with a key already minted from the dashboard) * When deploy or project commands fail with "API key is required" * To check current identity or switch between organizations * When the user needs to authenticate with a different org * For OTP-based self-provisioning from an AI agent, see [CLI OTP auth](./cli-auth) first ## Prerequisites * Node.js 22+ installed * npm available ## Install the CLI ```bash theme={null} # Install globally npm install -g codika # Verify installation codika --version ``` *** ## login Save an API key and create a named profile. Alias for `config set`. ```bash theme={null} codika login [options] ``` ### Options | Option | Description | | ------------------ | ----------------------------------------------------------- | | `--api-key ` | API key (skips interactive prompt) | | `--base-url ` | Base URL override (defaults to production) | | `--name ` | Custom profile name (auto-derived from org name if omitted) | | `--skip-verify` | Save without verifying the key against the API | ### Behavior 1. Prompts for API key (masked input) unless `--api-key` is provided 2. Validates the key against the Codika platform API (unless `--skip-verify`) 3. Stores profile metadata: org ID, org name, key name, scopes, creation date, expiry date 4. Sets the new profile as active ### Examples ```bash theme={null} # Interactive login codika login # Non-interactive login codika login --api-key cko_abc123def456 # Login with custom profile name codika login --api-key cko_abc123def456 --name staging # Login to a custom environment codika login --api-key cko_abc123def456 --base-url https://custom.api.example.com ``` *** ## whoami Show the current authenticated identity. ```bash theme={null} codika whoami [options] ``` ### Options | Option | Description | | -------- | -------------- | | `--json` | Output as JSON | ### Behavior Validates against the platform API for fresh data. Falls back to cached profile data if the network call fails. ### Output ``` Organization: Acme Corp Key name: production-key Key: cko_abc...xyz Scopes: deploy:use-case, workflows:trigger Expires: 2026-12-31 Profile: acme-corp ``` *** ## use Switch the active profile or list all profiles. ```bash theme={null} codika use [name] ``` ### Arguments | Argument | Description | | -------- | ---------------------------------------------------------------- | | `[name]` | Profile name to switch to (optional — lists profiles if omitted) | ### Options | Option | Description | | -------- | ------------------------------------------------- | | `--json` | Output machine-readable JSON with profile details | ### Behavior * **No argument**: Lists all profiles with an active marker (bullet) * **With argument**: Switches the active profile ### Output (list mode) ``` ● acme-corp (Acme Corp) staging (Acme Corp - Staging) other-org (Other Organization) ``` ### JSON output When called with `--json`, outputs an array of profile objects — useful for agents to match `project.json` `organizationId` to the correct profile: ```bash theme={null} codika use --json ``` ```json theme={null} [ { "name": "acme-corp", "organizationId": "org_abc123", "organizationName": "Acme Corp", "scopes": ["deploy:use-case", "workflows:trigger"], "keyPrefix": "cko_abc", "active": true }, { "name": "staging", "organizationId": "org_abc123", "organizationName": "Acme Corp - Staging", "scopes": ["deploy:use-case"], "keyPrefix": "cko_def", "active": false } ] ``` ### Examples ```bash theme={null} # List all profiles codika use # Switch to a specific profile codika use staging ``` *** ## logout Remove a profile. ```bash theme={null} codika logout [name] ``` ### Arguments | Argument | Description | | -------- | --------------------------------------------------- | | `[name]` | Profile name to remove (defaults to active profile) | ### Behavior Removes the specified profile. If it was the active profile, switches to the next available profile. *** ## config set Save API key and base URL. Same as `login`. ```bash theme={null} codika config set [options] ``` Options are identical to `login`. ## config show Display all stored profiles. ```bash theme={null} codika config show ``` ### Output ``` Profiles: ● acme-corp cko_abc...xyz (Acme Corp) staging cko_def...uvw (Acme Corp - Staging) ``` Exit code 0 if profiles exist, 1 if none. ## config clear Remove configuration. ```bash theme={null} codika config clear [options] ``` ### Options | Option | Description | | ------------------ | ------------------------------------------------ | | `--profile ` | Remove only this profile (clears all if omitted) | ### Examples ```bash theme={null} # Clear a specific profile codika config clear --profile staging # Clear all profiles and configuration codika config clear ``` *** ## Configuration storage | Item | Location | | ----------- | ---------------------------------------------- | | Config file | `~/.config/codika/config.json` | | Permissions | `0o600` (owner read/write only) | | Format | Multi-profile JSON with active profile pointer | ## API key resolution priority 1. `--api-key` / `--api-url` flag on any command 2. `CODIKA_API_KEY` / `CODIKA_BASE_URL` environment variable 3. Active profile in config file 4. Production default (base URL only) ## Organization-aware profile selection When `project.json` in a use case folder contains an `organizationId`, the CLI automatically selects the matching profile for deployment commands — even if a different profile is currently active. ## Error reference | Error | Cause | Fix | | ----------------------- | ------------------------------------ | ------------------------------------------------ | | "API key is required" | No key provided or found | Run `codika login` | | "Invalid API key" | Key is wrong or expired | Check with `codika whoami`, re-login | | "EACCES" on npm install | Permission denied | Use `sudo npm install -g` or fix npm permissions | | Wrong org on deploy | Active profile doesn't match project | Use `codika use ` | # CLI OTP Auth Source: https://doc.codika.io/operations/cli-auth Create a Codika account and mint a cko_ API key from the terminal using a 6-digit OTP. No browser required. ## When to use * An AI agent (or a user in a fresh terminal) needs a working Codika `cko_` API key and can receive email — but can't open a browser, run OAuth, or visit the dashboard. * The user wants to sign up for Codika and start deploying workflows in a single shell session. * A CI/CD job needs a short-lived key scoped to one organization, minted without leaving the terminal. The classic dashboard-paste path (`codika login --api-key cko_…`) still works — see [authentication](./authentication). This page documents the alternative: OTP-based self-provisioning. ## How it works Two commands per flow. The backend sends a 6-digit code to the email; the CLI sends the code back; the backend mints a `cko_` key and returns the raw key exactly once. The CLI saves it as a new profile in `~/.config/codika/config.json` and activates it. ``` ┌──────────────┐ signup-request ┌────────────┐ email (6-digit code) ┌────────┐ │ codika auth │ ───────────────────► │ Codika │ ──────────────────────────►│ User │ │ signup-request│ │ backend │ │ │ └──────────────┘ └────────────┘ └────────┘ ▲ │ │ signup-complete (email + code) │ └───────────────────────────────────────┘ ┌────────────────┐ │ cko_ saved in │ │ ~/.config/cod… │ └────────────────┘ ``` OTP security constants: | Constant | Value | | ---------------------- | ------------------------- | | Code length | 6 digits | | TTL | 10 minutes | | Failed-attempt lockout | 5 attempts → code deleted | | Min resend interval | 30 seconds | | Per-email cap | 20 requests / hour | | Per-IP cap | 60 requests / hour | *** ## codika auth signup-request Request an OTP for a brand-new signup. ```bash theme={null} codika auth signup-request --email [--json] ``` ### Options | Option | Description | | ---------------------------- | ----------------------------------------------------------------------- | | `--email ` (required) | Email address to register | | `--base-url ` | Codika API base URL override (default: production) | | `--api-url ` | Full URL to the `cliRequestSignupOtp` endpoint (overrides `--base-url`) | | `--json` | Emit JSON output | ### Response (`--json`) ```json theme={null} { "success": true, "data": { "email": "you@example.com", "expiresInSeconds": 600 } } ``` ### Errors | Code | Status | Meaning | Next action | | ---------------------------------- | ------ | --------------------------------- | ----------------------------- | | `EMAIL_REQUIRED` / `EMAIL_INVALID` | 400 | Missing or malformed email | Fix the flag | | `USER_ALREADY_HAS_ORGANIZATION` | 409 | Email already owns an org | Switch to `login-request` | | `OTP_RESEND_COOLDOWN` | 429 | Request spam (within 30s) | Wait `details.retryInSeconds` | | `EMAIL_RATE_LIMITED` | 429 | 20+ requests/hour from this email | Wait and retry | | `IP_RATE_LIMITED` | 429 | 60+ requests/hour from this IP | Wait and retry | | `INTERNAL` | 500 | Backend hiccup | Retry in a few seconds | *** ## codika auth signup-complete Verify the OTP and, in one atomic flow, create the Firebase Auth user, create the organization (with n8n error workflow + webhook auth credential seeded), and mint a `cko_` API key with the 10 default scopes. ```bash theme={null} codika auth signup-complete --email --code [options] ``` ### Options | Option | Description | | -------------------------------------- | ---------------------------------------------------------- | | `--email ` (required) | Email that received the OTP | | `--code ` (required) | 6-digit code from the email | | `--company ` | Organization name (default: "My Organization") | | `--description ` | Optional organization description | | `--key-name ` | Label for the minted API key (default: "CLI default key") | | `--key-expires-in ` | 1–365; omit for no expiry | | `--name ` | Local profile name (auto-derived from org name if omitted) | | `--base-url ` / `--api-url ` | URL overrides | | `--json` | Emit JSON output | ### Response (`--json`) ```json theme={null} { "success": true, "data": { "profileName": "my-organization", "organizationId": "org_...", "organizationName": "My Organization", "isNewUser": true, "apiKey": { "keyId": "019d...", "keyPrefix": "cko_aB12", "name": "CLI default key", "scopes": [ "deploy:use-case","projects:create","workflows:trigger", "executions:read","instances:read","instances:manage", "skills:read","integrations:manage","api-keys:manage","projects:read" ], "createdAt": "2026-..." } } } ``` The raw key is saved to `~/.config/codika/config.json` and does **not** appear in the JSON output (other than masked) after save. It is only available inside the CLI's profile. ### Errors | Code | Status | Meaning | Next action | | ------------------------------- | ------- | ---------------------------------------- | --------------------------- | | `OTP_INVALID` | 400 | Wrong code (`details.attemptsRemaining`) | Re-read email, retry | | `OTP_NOT_FOUND` | 404 | No pending code for this email | Re-run `signup-request` | | `OTP_EXPIRED` | 410 | Code older than 10 minutes | Re-run `signup-request` | | `OTP_ALREADY_USED` | 409 | Code already consumed | Re-run `signup-request` | | `OTP_PURPOSE_MISMATCH` | 409 | Crossed signup/login codes | Re-run the matching request | | `OTP_LOCKED_OUT` | 429 | 5+ failed attempts | Re-run `signup-request` | | `USER_ALREADY_HAS_ORGANIZATION` | 409 | Raced with another signup | Switch to `login-*` | | `COMPANY_NAME_TOO_LONG` | 400 | `--company` > 100 chars | Shorten | | `INVALID_EXPIRES_IN_DAYS` | 400 | `--key-expires-in` outside 1–365 | Fix or omit | | `ORGANIZATION_CREATION_FAILED` | 400–500 | Backend rejected org creation | Surface `message`, retry | | `INTERNAL` | 500 | Backend hiccup | Retry | *** ## codika auth login-request Same shape as `signup-request`, but for existing accounts. ```bash theme={null} codika auth login-request --email [--json] ``` ### Errors specific to login | Code | Status | Meaning | Next action | | -------------------------- | ------ | ------------------------- | -------------------------- | | `USER_NOT_FOUND` | 404 | No account for this email | Switch to `signup-request` | | `USER_HAS_NO_ORGANIZATION` | 409 | Account exists but no org | Switch to `signup-request` | *** ## codika auth login-complete Verify the OTP and mint a fresh `cko_` key for one of the user's organizations. ```bash theme={null} codika auth login-complete --email --code \ [--organization-id ] [--key-name ] [--key-expires-in ] \ [--name ] [--base-url ] [--api-url ] [--json] ``` Each `login-complete` mints a **new** key. Previous keys remain valid until revoked from the dashboard. ### Multi-org handling Codika users can belong to multiple organizations. If the user has more than one and `--organization-id` is not provided, the backend returns: ```json theme={null} { "success": false, "status": 409, "error": { "code": "MULTIPLE_ORGANIZATIONS", "message": "Account belongs to multiple organizations. Specify which one to mint a key for.", "nextAction": "Re-run `login-complete` with `--organization-id ` for the target org.", "details": { "organizations": [ { "id": "org_abc", "name": "Acme" }, { "id": "org_def", "name": "Beta Corp" } ] } } } ``` The agent should surface the list, let the user pick, then re-run with `--organization-id `. ### Other login-specific errors | Code | Status | Meaning | Next action | | -------------------------- | ------ | -------------------------------------------------------- | ------------------------------------ | | `ORGANIZATION_NOT_MEMBER` | 403 | `--organization-id` doesn't match any of the user's orgs | Pick from `details.organizations` | | `MAX_API_KEYS_REACHED` | 429 | Org already has 20 active keys | Revoke one from the dashboard, retry | | `USER_HAS_NO_ORGANIZATION` | 409 | All orgs were deleted between request and complete | Run `signup-request` | *** ## Agent recipe — optimistic signup, fallback to login ``` 1. codika auth signup-request --email $E --json - success → prompt user for OTP, go to step 2 - USER_ALREADY_HAS_ORGANIZATION → go to step 4 (login) - any other error → surface + abort 2. codika auth signup-complete --email $E --code $C --json - success → done - USER_ALREADY_HAS_ORGANIZATION → go to step 4 (login) - OTP_* recoverable → reprompt or re-request 3. --- unreached in the optimistic path --- 4. codika auth login-request --email $E --json - success → prompt user for OTP, go to step 5 - USER_NOT_FOUND | USER_HAS_NO_ORGANIZATION → go to step 1 (signup) 5. codika auth login-complete --email $E --code $C --json - success → done - MULTIPLE_ORGANIZATIONS → show details.organizations, get user pick, re-run with --organization-id - ORGANIZATION_NOT_MEMBER → same ``` ## See also * [Authentication](./authentication) — profile management, dashboard-paste flow, resolution priority * [Create Organization](./create-organization) — standalone org creation via personal/admin key * [Create Organization Key](./create-organization-key) — adding additional API keys to an existing org # Create Organization Source: https://doc.codika.io/operations/create-organization Create a new organization on the Codika platform with optional self-hosted n8n configuration ## When to use * User wants to create a new organization for a team or client * Setting up a new workspace before creating projects and deploying use cases * Automating org provisioning via scripts or agents ## Prerequisites * `codika` CLI installed and authenticated * Personal key (`ckp_`) or admin key (`cka_`) with `organizations:create` scope ## Command ```bash theme={null} codika organization create [options] ``` ## Options | Option | Required | Description | Default | | ------------------------- | -------- | -------------------------------------------------------------------------------------- | ---------------- | | `--name ` | Yes | Organization name (2-100 characters) | — | | `--description ` | No | Organization description | — | | `--size ` | No | Organization size | — | | `--logo ` | No | Path to a logo image file (JPEG, PNG, or WebP, max 5MB). Uploaded to platform storage. | — | | `--n8n-base-url ` | No | Self-hosted n8n instance URL | Platform default | | `--n8n-api-key ` | No | Self-hosted n8n API key | Platform default | | `--store-credential-copy` | No | Store encrypted credential backup in Codika (only with self-hosted n8n) | `false` | | `--api-url ` | No | Override API URL | — | | `--api-key ` | No | Override API key | — | | `--profile ` | No | Use a specific profile instead of the active one | — | | `--json` | No | JSON output | — | ### Size values `solo`, `2-10`, `11-50`, `51-200`, `201-1000`, `1000+` ## Behavior 1. If `--logo` is provided, reads the file, base64-encodes it, and sends it to the API for upload to platform storage 2. Calls the Codika platform API to create the organization 3. The authenticated user becomes the organization owner 4. Initializes free plan credits and n8n secrets 5. If self-hosted n8n flags are provided, validates the credentials before creating ## Examples ```bash theme={null} # Basic creation codika organization create --name "Acme Corp" # With description and size codika organization create \ --name "Acme Corp" \ --description "Main workspace for Acme team" \ --size "11-50" # With a logo codika organization create \ --name "Acme Corp" \ --logo ./acme-logo.png # With self-hosted n8n codika organization create \ --name "Enterprise Client" \ --n8n-base-url "https://n8n.enterprise.com" \ --n8n-api-key "n8n_api_xxxxx" # With self-hosted n8n and credential backup codika organization create \ --name "Enterprise Client" \ --n8n-base-url "https://n8n.enterprise.com" \ --n8n-api-key "n8n_api_xxxxx" \ --store-credential-copy # JSON output for scripting codika organization create --name "Test Org" --json ``` ## Output ``` ✓ Organization Created Successfully Organization ID: abc123-def456 Request ID: req-789 ``` ## Exit codes | Code | Meaning | | ---- | --------------------------------------------- | | `0` | Success | | `1` | API error (auth, network, server) | | `2` | CLI validation error (e.g., missing `--name`) | # Create Organization Key Source: https://doc.codika.io/operations/create-organization-key Create an API key for a Codika organization to enable deployments, workflow triggers, and management via CLI or API ## When to use * User needs an API key scoped to a specific organization for deployments or automation * Setting up CI/CD credentials for a team or client workspace * Creating keys for agents or scripts that trigger workflows within an org ## Prerequisites * `codika` CLI installed and authenticated * Personal key (`ckp_`) or admin key (`cka_`) with `api-keys:manage` scope * Target organization must already exist (see [Create Organization](/operations/create-organization)) ## Command ```bash theme={null} codika organization create-key [options] ``` ## Options | Option | Required | Description | Default | | -------------------------- | -------- | ------------------------------------------------ | --------- | | `--organization-id ` | Yes | Organization ID to create the key for | — | | `--name ` | Yes | Key name (for identification) | — | | `--scopes ` | Yes | Comma-separated list of scopes | — | | `--description ` | No | Key description | — | | `--expires-in-days ` | No | Number of days until the key expires | No expiry | | `--api-url ` | No | Override API URL | — | | `--api-key ` | No | Override API key | — | | `--profile ` | No | Use a specific profile instead of the active one | — | | `--json` | No | JSON output | — | ### Available scopes | Scope | Description | | --------------------- | ----------------------------------------------------- | | `deploy:use-case` | Deploy use cases, upload documents, and read metadata | | `projects:create` | Create new projects via API | | `projects:read` | List and inspect project details | | `workflows:trigger` | Trigger workflows and poll execution status | | `executions:read` | List and read execution details | | `instances:read` | Read process instance details | | `instances:manage` | Activate, deactivate, and manage instances | | `skills:read` | Download agent skill documents | | `integrations:manage` | Create, delete, and list integrations | | `api-keys:manage` | Create, update, and manage organization API keys | ## Behavior 1. Validates that the authenticated key has the `api-keys:manage` scope 2. Verifies the user is an admin or owner of the target organization 3. Creates a new organization key (`cko_`) with the specified scopes 4. Saves the new key as a profile and sets it as active 5. Returns the raw key once — it cannot be retrieved again after creation ## Examples ```bash theme={null} # Basic key creation codika organization create-key \ --organization-id "xwk9CcT440Vupa8soIhY" \ --name "CI Deploy Key" \ --scopes "deploy:use-case,workflows:trigger" # With description and expiry codika organization create-key \ --organization-id "xwk9CcT440Vupa8soIhY" \ --name "Agent Key" \ --scopes "deploy:use-case,workflows:trigger,integrations:manage" \ --description "Key for autonomous agent deployments" \ --expires-in-days 90 # JSON output for scripting codika organization create-key \ --organization-id "xwk9CcT440Vupa8soIhY" \ --name "Script Key" \ --scopes "deploy:use-case,workflows:trigger" \ --json ``` ## Output ``` ✓ Organization API Key Created Successfully ⚠ Save the API key below — it will not be shown again. API Key: cko_xxxxxxxxxxxxxxxxxxxx Key Prefix: cko_xxxxxxxx Key ID: abc123-def456 Name: CI Deploy Key Scopes: deploy:use-case, workflows:trigger Created: 3/30/2026 Request ID: req-789 Saved as profile "org-api-key-ci-deploy-key" (now active) ``` The raw key is displayed only once at creation time. Store it securely — it cannot be retrieved later. ## Exit codes | Code | Meaning | | ---- | --------------------------------------------------------------------------------- | | `0` | Success | | `1` | API error (auth, network, server) | | `2` | CLI validation error (e.g., missing `--organization-id`, `--name`, or `--scopes`) | # Create Project Source: https://doc.codika.io/operations/create-project Create a new project on the Codika platform and link it to a use case folder via project.json for org-aware deployment ## When to use * User wants to create a new project for deploying use cases * Before deploying if no project exists for the use case folder * When `project.json` is missing and deployment requires a project ID ## Prerequisites * `codika` CLI installed and authenticated * Valid API key with appropriate scopes ## Command ```bash theme={null} codika project create [options] ``` ## Options | Option | Required | Description | Default | | ----------------------------- | --------------- | ------------------------------------------------ | ---------------- | | `--name ` | Yes | Project display name | — | | `--description ` | No | Project description | — | | `--template-id ` | No | Template ID for project setup | Platform default | | `--organization-id ` | Admin keys only | Specify target organization | — | | `--path ` | Recommended | Write `project.json` to this directory | — | | `--project-file ` | No | Custom filename for project file | `project.json` | | `--api-url ` | No | Override API URL | — | | `--api-key ` | No | Override API key | — | | `--profile ` | No | Use a specific profile instead of the active one | — | | `--json` | No | JSON output | — | ## Behavior 1. Calls the Codika platform API to create the project 2. Creates a project in the specified (or inferred) organization 3. If `--path` is provided, writes `project.json` containing `projectId` and `organizationId` ## Recommended usage Always use `--path .` when creating a project for a use case folder: ```bash theme={null} cd my-use-case codika project create --name "My Automation" --path . ``` This writes `project.json`: ```json theme={null} { "projectId": "abc123", "organizationId": "org_def456" } ``` Benefits of `project.json`: * Enables **org-aware profile selection** during deployment * **Auto-resolves** `processInstanceId` for trigger and get commands * Stores `devProcessInstanceId` after first deploy * Stores `prodProcessInstanceId` after first publish ## Examples ```bash theme={null} # Create and link to current directory codika project create --name "Email Automation" --path . # Create with description codika project create \ --name "CRM Reporter" \ --description "Weekly pipeline reports to Slack" \ --path ./crm-reporter # Create without saving locally codika project create --name "Quick Test" # For admin keys targeting a specific org codika project create \ --name "Team Tool" \ --organization-id org_abc123 \ --path . # JSON output codika project create --name "My Project" --json ``` ## Output ``` ✓ Project created Project ID: abc123 Written: ./email-automation/project.json ``` ## Exit codes | Code | Meaning | | ---- | --------------------------------------------- | | `0` | Success | | `1` | API error (auth, network, server) | | `2` | CLI validation error (e.g., missing `--name`) | # Deploy Data Ingestion Source: https://doc.codika.io/operations/deploy-data-ingestion Deploy a process-level data ingestion configuration (RAG/embedding pipeline) to the Codika platform with independent versioning ## When to use * Deploy a data ingestion workflow (document embedding pipeline) * After creating or modifying data ingestion configuration in `config.ts` * The use case has a `getDataIngestionConfig()` export in `config.ts` ## Prerequisites * `codika` CLI installed and authenticated * A use case folder with `config.ts` exporting `getDataIngestionConfig()` and a `data-ingestion/` folder with exactly one workflow JSON file * A project to deploy to (via `project.json`) ## Use case folder structure ``` my-use-case/ project.json config.ts # Must export getDataIngestionConfig() data-ingestion/ .json # Exactly one workflow JSON file (auto-discovered) ``` ## Command ```bash theme={null} codika deploy process-data-ingestion [options] ``` ## Arguments | Argument | Description | | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | `` | Path to use case folder (config.ts must export `getDataIngestionConfig()`, and `data-ingestion/` folder must contain exactly one workflow JSON file) | ## Options | Option | Description | Default | | ---------------------------- | ----------------------------------------------------------- | ------------------------------- | | `--api-url ` | Override API URL | — | | `--api-key ` | Codika API key | `CODIKA_API_KEY` env or profile | | `--project-id ` | Override project ID | `project.json` | | `--project-file ` | Path to custom project file (e.g., `project-client-a.json`) | `project.json` | | `--patch` | Patch version bump (default) | — | | `--minor` | Minor version bump | — | | `--major` | Major version bump | — | | `--target-version ` | Deploy to explicit API version (e.g., `3.0`) | — | | `--profile ` | Use a specific profile instead of the active one | — | | `--json` | JSON output | — | ## What happens on deploy 1. `config.ts` is loaded — `getDataIngestionConfig()` is read 2. The CLI auto-discovers the single `.json` file in `data-ingestion/` 3. Project ID is resolved from `--project-id` > `project.json` 4. Configuration is sent to the platform 5. On success: * `version.json` is updated with the new `dataIngestionVersion` * Deployment is archived in `deployments/{projectId}/data-ingestion/{apiVersion}/` * `project-info.json` is updated with the version mapping * `project.json` is updated with `dataIngestionDeployments` map ## Version tracking Data ingestion has its own version line, separate from use case deployments: ```json theme={null} // version.json { "version": "1.0.4", "dataIngestionVersion": "1.1.0" } ``` ```json theme={null} // project.json (partial) { "dataIngestionDeployments": { "1.0": { "dataIngestionId": "di-abc123", "createdAt": "2025-01-20T14:30:00.000Z", "webhookUrls": { "embed": "https://n8n.example.com/webhook/embed-xxx", "delete": "https://n8n.example.com/webhook/delete-xxx" } } } } ``` ## Key differences from use case deployment | Aspect | Use Case Deploy | Data Ingestion Deploy | | ------------- | --------------------------------------------------- | --------------------------------------------------- | | Command | `deploy use-case` | `deploy process-data-ingestion` | | Scope | Per-user instance (dev/prod) | Per-process (shared by all users) | | Versioning | Semantic (X.Y.Z) + API (X.Y) | Simple (X.Y) + local (X.Y.Z) | | Notifications | Triggers "update available" | Does NOT trigger notifications | | Version flags | `--patch`, `--minor`, `--major`, `--target-version` | `--patch`, `--minor`, `--major`, `--target-version` | ## Examples ```bash theme={null} # Default deployment (minor bump) codika deploy process-data-ingestion ./my-use-case # Major version bump codika deploy process-data-ingestion ./my-use-case --major # Explicit version codika deploy process-data-ingestion ./my-use-case --target-version 3.0 # JSON output for CI codika deploy process-data-ingestion ./my-use-case --json ``` ## Output ``` ✓ Data Ingestion Deployment Successful Data Ingestion ID: di-abc123 API Version: 1.2 Local Version: 1.0.0 -> 1.1.0 Project ID: proj-456 Webhook (embed): https://n8n.example.com/webhook/embed-xxx Webhook (delete): https://n8n.example.com/webhook/delete-xxx ``` ## Exit codes | Code | Meaning | | ---- | ------------------------------- | | `0` | Deployment successful | | `1` | API error or validation failure | # Deploy Documents Source: https://doc.codika.io/operations/deploy-documents Upload use case documentation (stage 1-4 markdown files) to the Codika platform with automatic versioning ## When to use * Upload or deploy use case documents to the platform * After creating or updating stage markdown files in `documents/` * When deploying documentation alongside a use case ## Prerequisites * `codika` CLI installed and authenticated * A use case folder with a `documents/` subfolder containing stage markdown files * A project to deploy to (via `project.json` or `PROJECT_ID` in `config.ts`) ## Document folder structure ``` my-use-case/ project.json documents/ 1_business_requirements.md 2_solution_architecture.md 3_detailed_design.md 4_implementation_plan.md ``` Files must follow the pattern `{stage}_{name}.md`: | Pattern | Stage | Example Title | | -------- | ----- | ----------------------- | | `1_*.md` | 1 | "Business Requirements" | | `2_*.md` | 2 | "Solution Architecture" | | `3_*.md` | 3 | "Detailed Design" | | `4_*.md` | 4 | "Implementation Plan" | Not all stages are required — the CLI uploads whichever stages exist. ## Command ```bash theme={null} codika deploy documents [options] ``` ## Arguments | Argument | Description | | -------- | -------------------------------------------------------------------------------------- | | `` | Path to use case folder (must contain a `documents/` folder with stage markdown files) | ## Options | Option | Description | Default | | ----------------------- | ------------------------------------------------ | -------------- | | `--project-id ` | Override project ID | `project.json` | | `--project-file ` | Path to custom project file | `project.json` | | `--api-url ` | Override API URL | — | | `--api-key ` | Override API key | Profile | | `--profile ` | Use a specific profile instead of the active one | — | | `--json` | JSON output | — | ## What happens on deploy 1. Scans `documents/` for files matching `{1,2,3,4}_*.md` 2. For each file: derives title from filename, extracts summary from first paragraph (max 200 chars) 3. Resolves project ID: `--project-id` > `project.json` > `config.ts` 4. Uploads all documents to the platform in a single API call 5. Reports per-stage results (document ID, version, status) ## Document versioning Documents are versioned on the platform: * First upload for a stage creates version `1.0.0` * Subsequent uploads increment the minor version (e.g., `1.0.0` -> `1.1.0`) * Each document version is tracked in the platform's `version_history` collection ## Examples ```bash theme={null} # Deploy documents codika deploy documents ./my-use-case # With explicit project ID codika deploy documents ./my-use-case --project-id abc123 # JSON output for CI codika deploy documents ./my-use-case --json ``` ## Output ``` Reading document files... Stage 1: 1_business_requirements.md -> "Business Requirements" (2450 chars, ~380 words) Stage 2: 2_solution_architecture.md -> "Solution Architecture" (5120 chars, ~790 words) Uploading 2 document(s)... ✓ Documents Deployed Successfully Stage 1: v1.0.0 (doc-abc123) Stage 2: v1.0.0 (doc-def456) Request ID: req-789 ``` ## Exit codes | Code | Meaning | | ---- | ------------------------------- | | `0` | Documents deployed successfully | | `1` | Deployment failed | # Deploy Use Case Source: https://doc.codika.io/operations/deploy-use-case Deploy a use case folder to the Codika platform with version management, agent skill collection, deployment archiving, and org-aware API key resolution ## When to use * Deploy n8n workflows + config to the Codika platform * After creating or modifying workflow files * After a successful `verify use-case` check ## Prerequisites * `codika` CLI installed and authenticated * Use case folder with `config.ts` and `workflows/` directory * Platform project (via `project.json` or `PROJECT_ID` in config.ts) ## Recommended flow ```bash theme={null} cd my-use-case codika project create --name "My Project" --path . # If no project.json codika verify use-case . # Validate first codika deploy use-case . # Deploy ``` ## Command ```bash theme={null} codika deploy use-case [options] ``` ## Arguments | Argument | Description | | -------- | ------------------------------------------------------------------- | | `` | Path to use case folder (must contain `config.ts` and `workflows/`) | ## Options | Option | Description | Default | | ----------------------------- | ----------------------------------------------------------- | ------------------------------- | | `--api-url ` | Codika API URL | `CODIKA_API_URL` env or profile | | `--api-key ` | Codika API key | `CODIKA_API_KEY` env or profile | | `--project-id ` | Override project ID | `project.json` or `config.ts` | | `--project-file ` | Path to custom project file (e.g., `project-client-a.json`) | `project.json` | | `--patch` | Patch version bump | Default | | `--minor` | Minor version bump | — | | `--major` | Major version bump | — | | `--target-version ` | Explicit API version | — | | `--additional-file ` | Add extra file (repeatable) | — | | `--json` | JSON output | — | | `--profile ` | Use a specific profile instead of the active one | — | | `--dry-run` | Preview without calling API | — | ## Version strategy | Flag | Local version change | API version strategy | | ---------------------- | -------------------- | ------------------------ | | `--patch` (default) | 1.0.0 → 1.0.1 | `minor_bump` | | `--minor` | 1.0.1 → 1.1.0 | `minor_bump` | | `--major` | 1.1.0 → 2.0.0 | `major_bump` | | `--target-version 3.0` | Unchanged | `explicit` (version 3.0) | ## What happens on deploy 1. **Read** `version.json` for current version 2. **Validate** the use case (same as `verify use-case`) 3. **Bump** version based on flags 4. **Resolve** project ID: `--project-id` > `--project-file` > `project.json` > `config.ts` 5. **Resolve** API key: `--api-key` > env > org-matching profile > active profile 6. **Package** all workflow files 7. **Send** to the Codika platform API 8. **Collect** [agent skills](/concepts/agent-skills) from `skills/*/SKILL.md` (if any exist) 9. **On success:** * Update `version.json` with new local version * Save `devProcessInstanceId` to `project.json` * Save deployment to `deployments` map in `project.json` (version → templateId + timestamp) * Archive deployment in `deployments/{projectId}/process/{apiVersion}/` * Update `project-info.json` with version mapping **Agent skills are automatically included.** If your use case has a `skills/` folder with `SKILL.md` files, they are collected and sent with the deployment. Agents can then download them via `codika get skills`. No config.ts changes needed. The `deployments` map in `project.json` tracks all deployments by version — use it with `codika publish` to promote a deployment to production. **For parameter-only changes**, use [`codika rerun deployment`](/operations/rerun-deployment) instead. It updates deployment parameters on an existing instance without creating a new template version — no version bump, no new deployment archive. ## API key resolution (org-aware) If `project.json` contains `organizationId`, the CLI automatically selects the profile matching that org: 1. `--api-key` flag (always wins) 2. `CODIKA_API_KEY` environment variable 3. Profile matching `organizationId` from `project.json` 4. Active profile ## Dry-run mode Preview the deployment without calling the API: ```bash theme={null} codika deploy use-case ./my-use-case --dry-run ``` This validates the configuration, displays the deployment plan (versions, workflows, project ID, integrations), and exits with the validation status. ## Additional files Attach extra files to the deployment (e.g., documentation, data files): ```bash theme={null} codika deploy use-case ./my-use-case \ --additional-file "/absolute/path/to/readme.md:docs/readme.md" \ --additional-file "/absolute/path/to/data.json:data/seed.json" ``` Format: `absolutePath:relativePath` — the relative path determines where the file is stored in the deployment archive. ## Post-deploy files After a successful deployment, the folder contains: ``` my-use-case/ version.json # Updated with new version project.json # Updated with devProcessInstanceId + deployments map data-ingestion/ # Optional — process-level DI (deployed separately) embedding.json deployments/ {projectId}/ project-info.json # Version mapping history process/ {apiVersion}/ deployment-info.json config-snapshot.json workflows/*.json data-ingestion/ # Present if DI was deployed {apiVersion}/ deployment-info.json config-snapshot.json .json ``` Data ingestion workflows live in a separate `data-ingestion/` folder and are deployed independently via [`codika deploy process-data-ingestion`](/operations/deploy-data-ingestion). They have their own version line and do not trigger "update available" notifications. ## Examples ```bash theme={null} # Default deployment (patch bump) codika deploy use-case ./email-automation # Minor version bump codika deploy use-case ./email-automation --minor # Major version bump codika deploy use-case ./email-automation --major # Explicit API version codika deploy use-case ./email-automation --target-version 2.0 # Dry-run preview codika deploy use-case ./email-automation --dry-run # Deploy with specific project ID codika deploy use-case ./email-automation --project-id abc123 # JSON output for CI codika deploy use-case ./email-automation --json # With extra documentation file codika deploy use-case ./email-automation \ --additional-file "/path/to/readme.md:docs/readme.md" ``` ## Output ``` ✓ Deployed successfully Version: 1.2.4 (API: 1.3) Workflows: 3 Project: abc123 Instance: def456 ``` ## Exit codes | Code | Meaning | | ---- | ------------------------------- | | `0` | Deployment successful | | `1` | API error or validation failure | # Fetch Use Case Source: https://doc.codika.io/operations/fetch-use-case Download a deployed use case and its metadata documents from the Codika platform, with version selection and list mode ## When to use * Download a deployed use case from the platform * Restore a previously deployed use case to local files * Inspect what documents are stored for a project * Pull the latest deployed version locally ## Prerequisites * `codika` CLI installed and authenticated * Project ID of the deployed use case ## Resolving the project ID The CLI requires a **project ID**, not a folder path. If the user provides a use case folder path instead, read `project.json` from that folder to get the `projectId`: ```bash theme={null} cat /project.json # Use the "projectId" value in the command below ``` ## Command ```bash theme={null} codika get use-case [outputPath] [options] ``` ## Arguments | Argument | Description | | -------------- | --------------------------------------------------------- | | `` | Project ID of the deployed use case (from `project.json`) | | `[outputPath]` | Output directory (defaults to `./`) | ## Options | Option | Description | Default | | ------------------------ | ------------------------------------------------ | ------- | | `--target-version ` | Fetch specific version | Latest | | `--with-data-ingestion` | Include data ingestion workflow | `true` | | `--no-data-ingestion` | Exclude data ingestion workflow | — | | `--di-version ` | Data ingestion version in `X.Y` format | Latest | | `--list` | List documents without downloading | — | | `--api-url ` | Override API URL | — | | `--api-key ` | Override API key | — | | `--profile ` | Use a specific profile instead of the active one | — | | `--json` | JSON output | — | ## Behavior **Download mode** (default): 1. Fetches metadata documents from the API 2. Decodes file content 3. Writes files to the output directory **List mode** (`--list`): 1. Fetches document listing only 2. Displays file paths, sizes, and content types 3. Does not download any files ## Examples ```bash theme={null} # Download latest version codika get use-case abc123 # Download to a specific directory codika get use-case abc123 ./my-download # Download a specific version codika get use-case abc123 --target-version 1.2 # Download without data ingestion codika get use-case abc123 --no-data-ingestion # Download with specific data ingestion version codika get use-case abc123 --di-version 1.0 # List documents without downloading codika get use-case abc123 --list # JSON output codika get use-case abc123 --list --json ``` ## Output ### Download mode ``` ✓ Downloaded use case Project: abc123 Version: 1.3 DI Ver: 1.2 Files: 8 config.ts version.json workflows/main-workflow.json workflows/helper.json workflows/scheduler.json data-ingestion/embedding-ingestion.json ``` ### List mode ``` ✓ Found 4 document(s) Project: abc123 Version: 1.0 DI Version: 1.2 Organization: org_456 Documents: config.ts (8.1 KB, text/typescript) workflows/main-workflow.json (5.8 KB, application/json) workflows/sub-workflow.json (2.0 KB, application/json) data-ingestion/embedding-ingestion.json (3.2 KB, application/json) ``` ## Exit codes | Code | Meaning | | ---- | ------------------------------ | | `0` | Success | | `1` | API error or project not found | # Get Execution Source: https://doc.codika.io/operations/get-execution Fetch full n8n workflow execution details for debugging, with recursive sub-workflow traversal and slim output ## When to use * Debug a workflow execution that failed or returned unexpected results * Inspect node-level input/output for a specific execution * Fetch sub-workflow execution details recursively * Analyze execution timing and identify bottlenecks ## Prerequisites * `codika` CLI installed and authenticated * A deployed and triggered workflow * An execution ID (from the `trigger` command response) ## Typical debugging flow ```bash theme={null} # 1. Deploy codika deploy use-case . # 2. Trigger and get execution ID codika trigger main-workflow --poll --payload-file - <<'EOF' {"text": "test"} EOF # 3. Debug with full details codika get execution --deep --slim ``` ## Command ```bash theme={null} codika get execution [options] ``` ## Arguments | Argument | Description | | --------------- | ------------------------------------------- | | `` | Codika execution ID (from trigger response) | ## Options | Option | Description | Default | | ---------------------------- | ----------------------------------------------------------- | ------------------------------- | | `--process-instance-id ` | Explicit process instance ID | Auto-resolved from project.json | | `--project-file ` | Path to custom project file (e.g., `project-client-a.json`) | `project.json` | | `--path ` | Path to use case folder with `project.json` | Current directory | | `--deep` | Recursively fetch sub-workflow executions | Off | | `--slim` | Strip noise (`pairedItem`, `workflowData`) for readability | Off | | `-o, --output ` | Save to file instead of stdout | stdout | | `--api-url ` | Override API URL | — | | `--api-key ` | Override API key | — | | `--profile ` | Use a specific profile instead of the active one | — | | `--json` | JSON output | — | ## Recommended flags For most debugging, use both flags together: ```bash theme={null} codika get execution --deep --slim ``` * `--deep` gives you the complete execution tree including sub-workflows * `--slim` removes noisy metadata for cleaner, more readable output ## Process instance ID resolution 1. `--process-instance-id` flag 2. `devProcessInstanceId` in `--project-file` (if provided) 3. `devProcessInstanceId` in `project.json` at `--path` 4. `devProcessInstanceId` in `project.json` in current directory ## Deep mode When `--deep` is used, the CLI recursively fetches sub-workflow executions and attaches them as `_subExecutions` on the parent node that triggered them. This gives you the complete execution tree. ### How it works 1. Fetches the main execution 2. Identifies nodes that called sub-workflows (Execute Workflow nodes) 3. Recursively fetches each sub-workflow execution 4. Attaches results as `_subExecutions` on the parent node This builds a complete execution tree for multi-workflow use cases. ## Slim mode Strips noisy fields for cleaner output: * Removes `pairedItem` from all nodes * Removes `workflowData` from execution metadata Best used with `--deep` for debugging: `--deep --slim` ## Examples ```bash theme={null} # Basic execution details codika get execution exec_abc123 # Full recursive details, clean output codika get execution exec_abc123 --deep --slim # Save to file for analysis codika get execution exec_abc123 --deep --slim -o debug.json # Explicit process instance ID codika get execution exec_abc123 --process-instance-id pi_def456 # From a specific use case directory codika get execution exec_abc123 --path ./my-use-case ``` ## Output ``` Execution: exec_abc123 Status: success Duration: 12.3s n8n ID: n8n_xyz789 Nodes: 8 ✓ Webhook Trigger (0.1s) ✓ Codika Init (0.3s) ✓ Fetch Data (2.1s) ✓ Process Results (0.5s) ✓ Call Sub-Workflow (8.2s) └── Sub-workflow execution: ✓ Execute Workflow Trigger (0.0s) ✓ Transform Data (0.4s) ✓ Generate PDF (7.5s) ✓ Upload File (0.3s) ✓ IF Success (0.0s) ✓ Codika Submit Result (0.1s) ``` ## Exit codes | Code | Meaning | | ---- | -------------------------------- | | `0` | Success | | `1` | API error or execution not found | # Get Instance Source: https://doc.codika.io/operations/get-instance Fetch process instance details — deployment parameters, status, version, and active workflows ## When to use * Check what deployment parameters (INSTPARM values) are set on a live instance * Verify the deployment status and version of an instance * See which workflows are deployed and their n8n workflow IDs * Confirm an instance is active before triggering workflows ## Prerequisites * `codika` CLI installed and authenticated * A deployed process instance (via `deploy use-case` or the dashboard) * API key with `instances:read` scope ## Typical workflow ```bash theme={null} # 1. Deploy a use case codika deploy use-case . # 2. Rerun the deployment with parameters codika rerun deployment --param TO_EMAILS='["ops@acme.com"]' # 3. Verify the parameters are set correctly codika get instance --environment prod # 4. If wrong, rerun the deployment with corrected parameters codika rerun deployment --environment prod --param TO_EMAILS='["correct@acme.com"]' ``` ## Command ```bash theme={null} codika get instance [processInstanceId] [options] ``` ## Arguments | Argument | Description | | --------------------- | ---------------------------------------------------------------- | | `[processInstanceId]` | Process instance ID (optional — auto-resolved from project.json) | ## Options | Option | Description | Default | | ----------------------- | ------------------------------------------------------------------ | ----------------- | | `--path ` | Path to use case folder with `project.json` | Current directory | | `--project-file ` | Path to custom project file (e.g., `project-client-a.json`) | `project.json` | | `--environment ` | Environment: `dev` or `prod` | `dev` | | `--workflows` | Show expanded workflow details (triggers, activation status, cost) | — | | `--api-url ` | Override API URL | — | | `--api-key ` | Override API key | — | | `--profile ` | Use a specific profile instead of the active one | — | | `--json` | Output as JSON | — | ## Process instance ID resolution The instance ID is resolved in this order: 1. Positional argument (explicit ID) 2. `project.json` in `--path` directory — uses `devProcessInstanceId` or `prodProcessInstanceId` based on `--environment` 3. `project.json` in current directory — same environment-aware selection Use `--environment prod` to target the production instance from project.json. ## Examples ```bash theme={null} # Explicit instance ID codika get instance 019d312f-517c-726e-83ac-b678f2ad6afc # From a use case folder (dev instance) codika get instance --path ./my-use-case # Production instance from project.json codika get instance --environment prod # JSON output for scripting codika get instance --environment prod --json # With a custom project file codika get instance --project-file project-client-a.json --environment prod # Expanded workflow details (triggers, activation, cost) codika get instance --workflows ``` ## Output ### Human-readable (default) ``` ✓ Process Instance Instance ID: 019d312f-517c-726e-83ac-b678f2ad6afc Process ID: 11fe8iPQ4pBlskVIknz4 Environment: prod Status: deployed (active) Version: 1.50 Title: Creafid Receipt Processor Deployment Parameters: TO_EMAILS: [] (empty) CC_EMAILS: [] (empty) Workflows: - http-process-receipt (n8n: NGC6dwX7WL1F29DI) - http-get-receipts (n8n: XE4RRqOIaJF1m8Fu) - http-manage-clients (n8n: o1bvAUtugGH9PgRr) ``` ### With `--workflows` flag ``` ✓ Process Instance Instance ID: 019d312f-517c-726e-83ac-b678f2ad6afc ... Workflows: http-process-receipt n8n ID: NGC6dwX7WL1F29DI Active: yes Triggers: http (POST) Cost: 0.02 credits scheduled-report n8n ID: XE4RRqOIaJF1m8Fu Active: yes Triggers: schedule (0 6 * * *) ``` ### JSON output with `--workflows` (`--json`) ```json theme={null} { "success": true, "data": { "processInstanceId": "019d444d-...", "deployment": { "workflows": [ { "workflowId": "competitor-news-monitoring", "n8nWorkflowId": "pE5dKk7zbLQ6hdLg", "workflowName": "Competitor News Monitoring", "n8nWorkflowIsActive": true, "triggers": [ { "type": "http", "method": "POST" }, { "type": "schedule", "cronExpression": "0 8 * * *", "timezone": "Europe/Brussels" } ], "cost": 25, "integrationUids": ["tavily"] } ] } } } ``` Without `--workflows`, each workflow only contains `workflowId`, `n8nWorkflowId`, and `workflowName` (backward compatible). ### JSON output (`--json`) ```json theme={null} { "success": true, "data": { "processInstanceId": "019d312f-517c-726e-83ac-b678f2ad6afc", "processId": "11fe8iPQ4pBlskVIknz4", "environment": "prod", "isActive": true, "archived": false, "currentVersion": "1.50", "title": "Creafid Receipt Processor", "organizationId": "xwk9CcT440Vupa8soIhY", "installedAt": "2026-03-27T10:00:00.000Z", "lastExecutedAt": "2026-03-31T14:30:00.000Z", "deployment": { "deploymentInstanceId": "abc123", "deploymentStatus": "deployed", "deploymentParameters": { "TO_EMAILS": [], "CC_EMAILS": [] }, "deploymentInputSchema": [], "workflows": [ { "workflowId": "http-process-receipt", "n8nWorkflowId": "NGC6dwX7WL1F29DI", "workflowName": "Process Receipt (HTTP)" } ] } }, "requestId": "019d312f-..." } ``` ## Status values | Status | Meaning | | ------------------- | --------------------------------- | | `deployed (active)` | Workflows are deployed and active | | `deployed (paused)` | Workflows are deployed but paused | | `deploying` | Deployment is in progress | | `pending` | Awaiting first deployment | | `failed` | Deployment failed | | `archived` | Instance has been archived | ## Exit codes | Code | Meaning | | ---- | ----------------------------------------------------------- | | `0` | Success | | `1` | API error or instance not found | | `2` | CLI validation error (missing instance ID, missing API key) | # Get Project Source: https://doc.codika.io/operations/get-project Fetch project details — status, deployment version, stages, and process info ## When to use * Inspect project details including deployment version and status * Check if a project has a published process * View the current stage information * Verify project configuration before deploying ## Prerequisites * `codika` CLI installed and authenticated * API key with `projects:read` scope * A valid project ID (from `list projects` or `project create`) ## Command ```bash theme={null} codika get project [options] ``` ## Arguments | Argument | Description | | ------------- | --------------------- | | `` | Project ID (required) | ## Options | Option | Description | Default | | ------------------ | ------------------------------------------------ | ------- | | `--api-url ` | Override API URL | — | | `--api-key ` | Override API key | — | | `--profile ` | Use a specific profile instead of the active one | — | | `--json` | Output as JSON | — | ## Examples ```bash theme={null} # Get project details codika get project wIkjqoLC88abc123 # JSON output codika get project wIkjqoLC88abc123 --json ``` ## Output ### Human-readable (default) ``` ✓ Project Project ID: wIkjqoLC88abc123 Name: Creafid Receipt Processor Status: in_progress Published: yes Process ID: 11fe8iPQ4pBlskVIknz4 Deployment: v1.50 (2026-03-31) Stages: 2 (current: 2) Created: 2026-03-27 ``` ### JSON output (`--json`) ```json theme={null} { "success": true, "data": { "id": "wIkjqoLC88abc123", "name": "Creafid Receipt Processor", "description": "Processes receipts via HTTP upload", "status": "in_progress", "hasPublishedProcess": true, "processId": "11fe8iPQ4pBlskVIknz4", "currentDeployment": { "version": "1.50", "deployedAt": "2026-03-31T10:00:00.000Z" }, "createdBy": "user123", "createdAt": "2026-03-27T10:00:00.000Z", "archived": false, "stageCount": 2, "currentStage": 2 }, "requestId": "019d312f-..." } ``` ## Access control * **Admin keys** (`cka_`): can access any project in any organization * **Org owners/admins**: can access all projects in their organization * **Regular members**: can only access projects they created (`createdBy` matches their user ID) The response does not expose sensitive internal fields like `roles`, `stages` configuration, or `documentTags`. Only summary data is returned. ## Exit codes | Code | Meaning | | ---- | ---------------------------------------------------------- | | `0` | Success | | `1` | API error or project not found | | `2` | CLI validation error (missing project ID, missing API key) | # Get Skills Source: https://doc.codika.io/operations/get-skills Download agent skill documents from a deployed process instance to discover available workflow endpoints and their documentation ## When to use * You need to discover what workflow endpoints are available for a process instance * You want to download skills to use with Claude Code or the Claude API * You need to inspect the available workflows and their input/output schemas * An agent needs to understand how to interact with a deployed use case ## Prerequisites * Authenticated with `codika login` or `CODIKA_API_KEY` environment variable * A deployed process instance (with `devProcessInstanceId` in project.json, or known ID) ## Command ```bash theme={null} codika get skills [processInstanceId] [options] ``` ## Arguments | Argument | Required | Description | | --------------------- | -------- | ------------------------------------------------------------ | | `[processInstanceId]` | No | Process instance ID. If omitted, resolves from project.json. | ## Options | Option | Default | Description | | ---------------------------- | ----------------- | ------------------------------------------------------ | | `--process-instance-id ` | — | Alternative to positional argument | | `--path ` | Current directory | Path to use case folder (to resolve from project.json) | | `--project-file ` | `project.json` | Custom project file name | | `-o, --output ` | `./skills` | Output directory for skill files | | `--stdout` | `false` | Print to stdout instead of writing files | | `--api-url ` | Production | Override API URL | | `--api-key ` | Active profile | Override API key | | `--profile ` | — | Use a specific profile instead of the active one | | `--json` | `false` | Structured JSON output | ## Process instance ID resolution Priority order: 1. Positional argument (highest) 2. `--process-instance-id` flag 3. `devProcessInstanceId` from project.json in `--path` directory 4. `devProcessInstanceId` from project.json in current directory ## How it works 1. Resolves process instance ID from flag, argument, or project.json 2. Calls `getProcessSkillsPublic` cloud function with API key auth 3. Reads skills from the process's active deployment instance 4. Writes each skill as a Claude-compatible directory: `{name}/SKILL.md` ## Examples ### From inside a use case folder ```bash theme={null} codika get skills ``` Resolves `devProcessInstanceId` from `project.json`. ### With explicit process instance ID ```bash theme={null} codika get skills abc123def456 ``` ### Download directly to Claude Code skills directory ```bash theme={null} codika get skills --output .claude/skills ``` Skills are immediately auto-discoverable by Claude Code. ### JSON output for scripting ```bash theme={null} codika get skills --json ``` ### Print all skills to stdout ```bash theme={null} codika get skills --stdout ``` ## Output ### Human-readable (default) ``` ✓ Downloaded 3 skill(s) to ./skills/ wat-direct-messaging/SKILL.md Sends a WhatsApp message to a list of phone numbers via Twilio Trigger: codika trigger http-direct-messaging wat-test-bot/SKILL.md Sends a test message and returns AI response without Twilio Trigger: codika trigger http-test-bot wat-event-weekly-digest/SKILL.md Sends a personalized weekly digest every Monday at 9 AM Trigger: codika trigger scheduled-event-weekly-digest To use with Claude Code, copy to .claude/skills/ ``` ### JSON output ```json theme={null} { "success": true, "processInstanceId": "abc123def456", "skillCount": 3, "skills": [ { "name": "wat-direct-messaging", "description": "Sends a WhatsApp message to a list of phone numbers via Twilio.", "workflowTemplateId": "http-direct-messaging", "contentMarkdown": "---\nname: wat-direct-messaging\n...", "relativePath": "skills/direct-messaging/SKILL.md" } ] } ``` ## Using downloaded skills ### With Claude Code ```bash theme={null} codika get skills --output .claude/skills ``` Claude Code auto-discovers skills in `.claude/skills/` and can use them in conversations. ### With the Claude API ```python theme={null} from anthropic.lib import files_from_dir skill = client.beta.skills.create( display_title="Direct Messaging", files=files_from_dir("./skills/wat-direct-messaging"), betas=["skills-2025-10-02"], ) ``` ### Triggering a workflow from a skill After reading a skill, trigger the workflow it describes: ```bash theme={null} codika trigger http-direct-messaging --payload-file input.json --poll ``` ## Error reference | Error | Cause | Fix | | --------------------------------- | ------------------------------ | ----------------------------------------------------------------- | | `Process instance ID is required` | No ID found | Provide ID or ensure project.json has `devProcessInstanceId` | | `API key is required` | No API key found | Run `codika login` or set `CODIKA_API_KEY` | | `No skills found` | Process has no skills deployed | Add `skills/` folder to use case and run `codika deploy use-case` | | `401 Unauthorized` | Invalid API key | Run `codika login` to refresh credentials | ## Exit codes | Code | Meaning | | ---- | --------------------------------- | | `0` | Success | | `1` | Error (API failure, auth failure) | # Initialize Use Case Source: https://doc.codika.io/operations/init-use-case Scaffold a new use case folder with config, template workflows, agent skills, version tracking, and optional platform project creation ## When to use * Start a new use case from scratch * Create the initial folder structure for an n8n workflow project * Bootstrap a new automation with correct Codika patterns ## Prerequisites * `codika` CLI installed * For project creation: authenticated via `codika login` (optional — scaffolding works without auth) ## Command ```bash theme={null} codika init [options] ``` ## Arguments | Argument | Description | | -------- | ----------------------------------- | | `` | Directory to create the use case in | ## Options | Option | Description | Default | | ----------------------- | ------------------------------------------------ | ------------------ | | `--name ` | Use case display name | Interactive prompt | | `--description ` | Use case description | Auto-generated | | `--icon ` | Lucide icon name | `Workflow` | | `--no-project` | Skip project creation on the platform | — | | `--project-id ` | Use existing project ID (no API call) | — | | `--no-install` | Skip npm install after scaffolding | Runs npm install | | `--project-file ` | Custom filename for the project file | `project.json` | | `--api-url ` | Override API URL | — | | `--api-key ` | Override API key | — | | `--profile ` | Use a specific profile instead of the active one | — | | `--json` | Output result as JSON | — | ## What it creates ``` my-use-case/ config.ts # Deployment configuration with 3 template workflows version.json # Version tracking, initialized to 1.0.0 project.json # Platform project ID and org ID (if project created) CLAUDE.md # Use case documentation for AI agents package.json # Dependencies (codika) tsconfig.json # TypeScript config for IDE type-checking .gitignore # Ignores node_modules/ node_modules/ # Installed automatically (unless --no-install) workflows/ main-workflow.json # HTTP-triggered parent workflow scheduled-report.json # Schedule-triggered workflow (Monday 9 AM) text-processor.json # Sub-workflow called by main workflow skills/ main-workflow/ SKILL.md # Agent skill for the HTTP workflow scheduled-report/ SKILL.md # Agent skill for the scheduled workflow ``` ### Agent skills The scaffold includes two [agent skills](/concepts/agent-skills) — one for each triggerable workflow. Skills are Claude-compatible `SKILL.md` files that describe how to interact with the workflow's endpoint. No skill is created for `text-processor` because sub-workflows are not directly triggerable. Skills are automatically collected and deployed when you run `codika deploy use-case`. ## Template workflows The scaffold generates three workflows that demonstrate different patterns: ### main-workflow\.json (HTTP trigger) * Webhook trigger with input validation * Codika Init (HTTP mode — extracts metadata) * Calls `text-processor` sub-workflow via `SUBWKFL` placeholder * Codika Submit Result / Report Error ### scheduled-report.json (Schedule trigger) * Schedule Trigger (cron) + manual Webhook * Codika Init (schedule mode — creates execution via API) * Business logic placeholder * Codika Submit Result / Report Error ### text-processor.json (Sub-workflow) * Execute Workflow Trigger (receives data from parent) * No Codika Init node * Processes data and returns result to parent | Feature | Where | | ---------------------------------- | ------------------------------------------- | | HTTP trigger with input validation | `main-workflow.json` | | Schedule trigger (Monday 9 AM) | `scheduled-report.json` | | Manual webhook fallback | `scheduled-report.json` | | Sub-workflow pattern | `text-processor.json` | | SUBWKFL placeholder | `main-workflow.json` calls `text-processor` | | Codika Init (HTTP mode) | `main-workflow.json` | | Codika Init (schedule mode) | `scheduled-report.json` | | Submit Result / Report Error | All parent workflows | | Placeholder usage | All workflows | ## Behavior 1. Creates the folder structure and generates all template files 2. If authenticated and `--no-project` is not set: * Creates a project on the Codika platform via API * Writes `projectId` and `organizationId` to `project.json` 3. If `--project-id` is provided: * Uses that ID without making an API call * Writes to `project.json` 4. Checks if a parent directory already has `codika` in its `package.json`: * If found (e.g., inside a monorepo): reuses the existing workspace, skips dependency setup * If not found: creates `package.json`, `tsconfig.json`, `.gitignore`, and runs `npm install` 5. If `--no-install` is set: creates the dependency files but skips `npm install` ## Project organization ### Single use case (default) When you scaffold a use case in a standalone directory, the CLI creates a self-contained project with its own `package.json` and dependencies: ```bash theme={null} codika init ./email-automation --name "Email Automation" ``` ``` email-automation/ config.ts version.json project.json package.json # Own dependencies tsconfig.json .gitignore node_modules/ # Own copy of codika workflows/ ... ``` This is the simplest approach — each use case is a self-contained, portable project. ### Multiple use cases (shared workspace) If you plan to manage multiple use cases in a single repository, create a shared workspace with one `package.json` at the root. All use cases share the same dependencies: ```bash theme={null} # 1. Set up the workspace mkdir my-automations && cd my-automations npm init -y npm install codika echo 'node_modules/' > .gitignore # 2. Scaffold use cases inside it codika init ./email-automation --name "Email Automation" codika init ./report-generator --name "Report Generator" codika init ./crm-sync --name "CRM Sync" ``` ``` my-automations/ package.json # Shared dependencies node_modules/ # Single copy of codika email-automation/ config.ts version.json workflows/ report-generator/ config.ts version.json workflows/ crm-sync/ config.ts version.json workflows/ ``` The CLI automatically detects the shared `package.json` and skips creating per-use-case dependency files. Each use case is still independently deployable — `codika deploy use-case ./email-automation` works regardless of the project structure. This is the recommended approach when you have multiple use cases, since it avoids duplicating `node_modules` and keeps everything in one place. ## Examples ```bash theme={null} # Interactive scaffold with auto project creation codika init ./email-automation --name "Email Automation" # Scaffold without creating a platform project codika init ./local-test --name "Local Test" --no-project # Scaffold with an existing project ID codika init ./my-tool --name "My Tool" --project-id abc123 # Non-interactive, full options codika init ./crm-sync \ --name "CRM Sync" \ --description "Syncs contacts between CRM and email" \ --icon "RefreshCw" ``` ## Next steps after init ```bash theme={null} # Verify the scaffold is valid codika verify use-case ./my-use-case # Deploy to the platform codika deploy use-case ./my-use-case ``` If you used `--no-project`, create a project before deploying: ```bash theme={null} codika project create --name "My Automation" --path ./my-use-case ``` ## Exit codes | Code | Meaning | | ---- | ----------------------------------------------------- | | `0` | Success | | `1` | Runtime error | | `2` | CLI validation error (e.g., directory already exists) | # Activate / Deactivate Instance Source: https://doc.codika.io/operations/instance-activate Activate or deactivate a deployed process instance to control whether its workflows are running ## When to use * Pause all workflows in an instance during maintenance or debugging * Resume workflows after maintenance is complete * Toggle between dev and prod environments (activating prod may auto-deactivate dev) * Temporarily disable a workflow without undeploying it ## Prerequisites * `codika` CLI installed and authenticated * A deployed process instance (`devProcessInstanceId` or `prodProcessInstanceId` in `project.json`) * API key with `instances:manage` scope ## Commands ```bash theme={null} codika instance activate [processInstanceId] [options] codika instance deactivate [processInstanceId] [options] ``` ## Arguments | Argument | Required | Description | | --------------------- | -------- | ------------------------------------------------------------- | | `[processInstanceId]` | No | Process instance ID. If omitted, resolved from `project.json` | ## Options | Option | Description | Default | | ----------------------- | ------------------------------------------------ | ----------------- | | `--path ` | Path to use case folder with `project.json` | Current directory | | `--project-file ` | Path to custom project file | `project.json` | | `--environment ` | Target environment (`dev` or `prod`) | `dev` | | `--api-url ` | Override API URL | — | | `--api-key ` | Override API key | — | | `--profile ` | Use a specific profile instead of the active one | — | | `--json` | JSON output | — | ## Process instance ID resolution The CLI resolves which process instance to target using this priority: 1. Positional argument `[processInstanceId]` (highest priority) 2. `project.json` field based on `--environment`: * `dev` → `devProcessInstanceId` * `prod` → `prodProcessInstanceId` If neither is found, the command exits with an error. ## Auto-toggle behavior **Environment auto-toggle.** Activating a prod instance may automatically deactivate the corresponding dev instance for the same process, and vice versa. This prevents both environments from running simultaneously and consuming duplicate resources. The CLI reports when an auto-toggle occurs. ## Examples ```bash theme={null} # Activate prod instance by ID codika instance activate pi_prod_789 # Deactivate dev instance by ID codika instance deactivate pi_dev_456 # Activate from use case folder (reads project.json) codika instance activate --environment prod # Deactivate from use case folder codika instance deactivate --environment dev # Custom project file codika instance activate --project-file project-client.json --environment prod # JSON output for automation codika instance activate pi_prod_789 --json ``` ## Output **Activate:** ``` ✓ Instance activated Instance: pi_prod_789 Environment: prod Status: active Workflows: 3 activated ``` **Deactivate:** ``` ✓ Instance deactivated Instance: pi_dev_456 Environment: dev Status: inactive Workflows: 3 deactivated ``` **With auto-toggle:** ``` ✓ Instance activated Instance: pi_prod_789 Environment: prod Status: active Workflows: 3 activated ⚠ Auto-deactivated dev instance pi_dev_456 ``` JSON output (`--json`): ```json theme={null} { "success": true, "processInstanceId": "pi_prod_789", "environment": "prod", "status": "active", "workflowsAffected": 3, "autoToggled": { "processInstanceId": "pi_dev_456", "environment": "dev", "status": "inactive" } } ``` ## Error reference | HTTP | Error | Fix | | ---- | -------------------------------- | ---------------------------------------------------------------------------- | | 401 | Invalid API key | Re-login with `codika login` | | 403 | Missing scope | Create key with `instances:manage` scope | | 404 | Instance not found | Check instance ID in `project.json` or pass as positional argument | | 409 | Instance already in target state | Instance is already active/inactive — no action needed | | 400 | Instance in failed state | Cannot activate a failed instance — fix with `codika rerun deployment` first | ## Exit codes | Code | Meaning | | ---- | ----------------------- | | `0` | State change successful | | `1` | API error | | `2` | CLI validation error | # List Executions Source: https://doc.codika.io/operations/list-executions List recent executions for a process instance with filtering by workflow, status, and result count ## When to use * Check the status of recent workflow runs at a glance * Find failed executions to investigate further * Monitor how often a workflow is triggered * Get an execution ID to pass to `get-execution` for node-level debugging ## Prerequisites * `codika` CLI installed and authenticated * A deployed process instance (`devProcessInstanceId` or `prodProcessInstanceId` in `project.json`) * API key with `executions:read` scope ## Command ```bash theme={null} codika list executions [options] ``` ## Arguments | Argument | Description | | --------------------- | ----------------------------------------------------- | | `` | Process instance ID (dev or prod) from `project.json` | ## Options | Option | Description | Default | | -------------------- | ------------------------------------------------ | ------------- | | `--workflow-id ` | Filter results to a specific workflow | All workflows | | `--failed-only` | Return only failed executions | Off | | `--limit ` | Number of executions to return (1–100) | `20` | | `--api-url ` | Override API URL | — | | `--api-key ` | Override API key | — | | `--profile ` | Use a specific profile instead of the active one | — | | `--json` | JSON output | — | ## Behavior 1. Fetches recent executions from the platform API 2. Returns lightweight summaries (no full result data — use `get execution` for that) 3. Sorted by creation time, newest first ## Dev vs Prod executions After deploying and publishing, `project.json` contains both instance IDs: ```json theme={null} { "devProcessInstanceId": "pi-dev-789", "prodProcessInstanceId": "pi-prod-999" } ``` Use `devProcessInstanceId` to list dev executions and `prodProcessInstanceId` to list prod executions. ## Examples ```bash theme={null} # List recent executions for dev instance codika list executions pi_dev_456 # Filter by workflow codika list executions pi_dev_456 --workflow-id main-workflow # Only failed executions codika list executions pi_dev_456 --failed-only # Limit results codika list executions pi_dev_456 --limit 5 # JSON output codika list executions pi_dev_456 --json # Prod executions (use prod instance ID from project.json) codika list executions pi_prod_789 ``` ## Output ``` ● Recent Executions (pi_dev_456...) ID Workflow Status Duration Created ────────────── ──────────────────── ────────── ────────── ─────────────────── exec-001abc main-workflow ✓ success 1.2s 2026-03-04 14:30:00 exec-002def main-workflow ✗ failed 0.8s 2026-03-04 14:00:00 └─ [HTTP Request] Connection refused exec-003ghi helper-workflow ⋯ pending - 2026-03-04 13:30:00 Showing 3 executions ``` Each row shows the execution ID (truncated), workflow ID, status with icon, duration, and creation timestamp. Failed executions show the error message and failed node name on the next line. Pass any execution ID to [`codika get execution `](/operations/get-execution) for full node-level details. Note: Zero executions is not an error — the CLI prints "No executions found." and exits with code 0. ## Error reference | HTTP | Error | Fix | | ---- | ------------------ | --------------------------------------- | | 401 | Invalid API key | Re-login with `codika login` | | 403 | Missing scope | Create key with `executions:read` scope | | 403 | No access | Process instance in different org | | 404 | Instance not found | Check process instance ID | ## Exit codes | Code | Meaning | | ---- | -------------------- | | `0` | Success | | `1` | API error | | `2` | CLI validation error | # List Instances Source: https://doc.codika.io/operations/list-instances List all process instances for an organization with filtering by environment, status, and archival state ## When to use * See all deployed process instances across an organization at a glance * Check instance status across environments (dev and prod) * Audit what is currently running in an organization * Find an instance ID to pass to `get instance` or `instance activate/deactivate` ## Prerequisites * `codika` CLI installed and authenticated * API key with `instances:read` scope ## Command ```bash theme={null} codika list instances [options] ``` ## Options | Option | Description | Default | | --------------------- | ------------------------------------------------ | ---------------- | | `--environment ` | Filter by environment (`dev` or `prod`) | All environments | | `--archived` | Include archived instances | Off | | `--limit ` | Number of instances to return | `50` | | `--api-url ` | Override API URL | — | | `--api-key ` | Override API key | — | | `--profile ` | Use a specific profile instead of the active one | — | | `--json` | JSON output | — | ## Behavior 1. Fetches all process instances for the authenticated organization 2. Returns lightweight summaries with status, environment, and version info 3. Sorted by last execution time, most recent first ## Examples ```bash theme={null} # List all instances codika list instances # Filter by environment codika list instances --environment prod # Include archived instances codika list instances --archived # Limit results codika list instances --limit 10 # JSON output for scripting codika list instances --json # Combine filters codika list instances --environment dev --limit 5 --json ``` ## Output ``` ● Process Instances (org: My Organization) Title Env Status Version Last Executed ──────────────────────── ────── ──────────── ───────── ─────────────────── Email Automation prod ✓ active v2.1.0 2026-03-30 14:30:00 Email Automation dev ○ inactive v2.2.0 2026-03-30 10:15:00 Weekly Report prod ✓ active v1.0.0 2026-03-29 08:00:00 Data Ingestion Pipeline dev ✗ failed v1.3.0 2026-03-28 16:45:00 Showing 4 instances ``` Each row shows the instance title, environment, status with icon, template version, and last execution timestamp. Instances with no executions show `—` in the Last Executed column. Note: Zero instances is not an error — the CLI prints "No instances found." and exits with code 0. ## Error reference | HTTP | Error | Fix | | ---- | --------------- | -------------------------------------------- | | 401 | Invalid API key | Re-login with `codika login` | | 403 | Missing scope | Create key with `instances:read` scope | | 403 | No access | Organization mismatch — check active profile | ## Exit codes | Code | Meaning | | ---- | --------- | | `0` | Success | | `1` | API error | # List Projects Source: https://doc.codika.io/operations/list-projects List projects in an organization with optional filtering by archive status ## When to use * Browse all projects in the authenticated organization * Check project status and deployment state * Find a project ID for subsequent commands like `get project` * List archived projects for cleanup ## Prerequisites * `codika` CLI installed and authenticated * API key with `projects:read` scope ## Command ```bash theme={null} codika list projects [options] ``` ## Options | Option | Description | Default | | ------------------ | ------------------------------------------------ | ------- | | `--archived` | Show archived projects instead of active ones | `false` | | `--limit ` | Number of results (max: 100) | `50` | | `--api-url ` | Override API URL | — | | `--api-key ` | Override API key | — | | `--profile ` | Use a specific profile instead of the active one | — | | `--json` | Output as JSON | — | ## Examples ```bash theme={null} # List active projects codika list projects # List archived projects codika list projects --archived # Limit results codika list projects --limit 10 # JSON output for scripting codika list projects --json ``` ## Output ### Human-readable (default) ``` ● Projects (xwk9CcT440...) Name Status Published Created ────────────────────────────────── ────────────── ────────── ────────── Creafid Receipt Processor ● in_progress yes 2026-03-27 Growth Analytics ○ draft no 2026-03-25 Showing 2 projects ``` ### JSON output (`--json`) ```json theme={null} { "success": true, "data": { "projects": [ { "id": "wIkjqoLC88...", "name": "Creafid Receipt Processor", "description": "Processes receipts via HTTP upload", "status": "in_progress", "hasPublishedProcess": true, "createdBy": "user123", "createdAt": "2026-03-27T10:00:00.000Z", "archived": false } ], "count": 1, "organizationId": "xwk9CcT440Vupa8soIhY" }, "requestId": "019d312f-..." } ``` ## Access control * **Admin keys** and **org admins/owners** see all projects in the organization * **Regular members** see only projects they created ## Exit codes | Code | Meaning | | ---- | -------------------------------------- | | `0` | Success | | `1` | API error | | `2` | CLI validation error (missing API key) | # Manage Integrations Source: https://doc.codika.io/operations/manage-integrations Configure, list, and delete integrations (API keys, credentials) for organizations and process instances via the CLI ## When to use * After deploying a use case that requires integrations (OpenAI, Supabase, etc.) * When setting up a new organization with required API keys * When rotating or updating integration credentials * When checking which integrations are connected ## Prerequisites * API key with `integrations:manage` scope * For process instance integrations: `project.json` with `devProcessInstanceId` ## Subcommands | Command | Description | | -------- | ------------------------------------------------- | | `set` | Create or update an integration | | `list` | List integrations and their status | | `delete` | Delete an integration | | `schema` | Fetch n8n credential schema for a credential type | *** ## `codika integration set` Creates an integration by encrypting secrets client-side and sending them to the platform. ```bash theme={null} codika integration set [options] ``` ### Arguments | Argument | Description | | --------------- | ------------------------------------------------------------ | | `integrationId` | Integration ID (e.g., `openai`, `supabase`, `cstm_acme_crm`) | ### Options | Option | Description | Default | | ----------------------------- | ----------------------------------------------- | ------------------- | | `--secret ` | Secret field (repeatable) | — | | `--secrets ` | JSON string with all secrets | — | | `--secrets-file ` | Path to JSON file with secrets | — | | `--metadata ` | Metadata field (repeatable) | — | | `--context-type ` | `organization`, `member`, or `process_instance` | Auto-detected | | `--process-instance-id ` | Process instance ID | From `project.json` | | `--path ` | Path to use case folder | Current directory | | `--project-file ` | Custom project file | `project.json` | | `--environment ` | `dev` or `prod` | `dev` | | `--custom-schema-file ` | Custom integration schema JSON | — | | `--force` | Delete existing and recreate | `false` | | `--profile ` | CLI profile to use | Active profile | | `--api-key ` | Override API key | — | | `--json` | Output as JSON | `false` | ### Secret input priority Secrets are merged with this priority (highest wins): 1. `--secret KEY=VALUE` flags 2. `--secrets '{"KEY":"VALUE"}'` JSON string 3. `--secrets-file path.json` file ### Examples ```bash theme={null} # Simple API key codika integration set openai --secret OPENAI_API_KEY=sk-proj-xxx # Multi-field credentials codika integration set supabase \ --secret SUPABASE_HOST=https://abc.supabase.co \ --secret SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiJ9... \ --path ./my-use-case # JSON input (best for automation) codika integration set anthropic \ --secrets '{"ANTHROPIC_API_KEY":"sk-ant-xxx"}' \ --json # Custom integration — schema auto-extracted from config.ts codika integration set cstm_acme_crm \ --secret API_KEY=acme_sk_xxx \ --path ./my-use-case \ --json # Custom integration — explicit schema file (fallback) codika integration set cstm_acme_crm \ --secret API_KEY=acme_sk_xxx \ --custom-schema-file ./schema.json \ --process-instance-id abc123 # Force overwrite codika integration set openai \ --secret OPENAI_API_KEY=sk-new-key \ --force ``` ### Custom integrations (cstm\_\*) Custom integrations require a schema defining their fields and n8n credential mapping. The CLI resolves this schema automatically: 1. **Auto-extraction (recommended):** When `--path` points to a use case folder (or you run from one), the CLI reads `config.ts` and extracts the matching schema from the `customIntegrations` array. No separate file needed. 2. **Explicit file:** Pass `--custom-schema-file` with a JSON file containing the `CustomIntegrationSchema`. ### OAuth integrations OAuth-based integrations (Gmail, Teams, Slack, etc.) cannot be configured from the CLI. The command will display the dashboard URL instead: ``` ⚠ google_gmail requires OAuth authentication. Connect it via the dashboard at: https://app.codika.io/organizations/.../integrations ``` *** ## `codika integration list` Lists integrations and their connection status. ```bash theme={null} codika integration list [options] ``` ### Options | Option | Description | Default | | ---------------------------- | ------------------------------------ | ------------------- | | `--context-type ` | `organization` or `process_instance` | `organization` | | `--process-instance-id ` | Process instance ID | From `project.json` | | `--path ` | Path to use case folder | Current directory | | `--project-file ` | Custom project file | `project.json` | | `--environment ` | `dev` or `prod` | `dev` | | `--profile ` | CLI profile to use | Active profile | | `--api-key ` | Override API key | — | | `--json` | Output as JSON | `false` | ### Examples ```bash theme={null} # List organization integrations codika integration list # List process instance integrations codika integration list --context-type process_instance --path ./my-use-case # JSON output codika integration list --json ``` *** ## `codika integration delete` Deletes an integration. Uses two-phase deletion by default — first shows dependent processes, then deletes with `--confirm`. ```bash theme={null} codika integration delete [options] ``` ### Arguments | Argument | Description | | --------------- | ------------------------ | | `integrationId` | Integration ID to delete | ### Options | Option | Description | Default | | ---------------------------- | ----------------------------------------------- | ------------------- | | `--context-type ` | `organization`, `member`, or `process_instance` | Auto-detected | | `--process-instance-id ` | Process instance ID | From `project.json` | | `--path ` | Path to use case folder | Current directory | | `--project-file ` | Custom project file | `project.json` | | `--environment ` | `dev` or `prod` | `dev` | | `--confirm` | Skip confirmation and delete immediately | `false` | | `--profile ` | CLI profile to use | Active profile | | `--api-key ` | Override API key | — | | `--json` | Output as JSON | `false` | ### Examples ```bash theme={null} # Check dependencies first codika integration delete openai # Delete immediately codika integration delete openai --confirm # Delete process instance integration codika integration delete supabase \ --confirm \ --process-instance-id abc123 ``` *** ## `codika integration schema` Fetches the n8n credential schema for a given credential type. Use this to discover which fields are required when creating a custom integration with any n8n credential type. ```bash theme={null} codika integration schema [options] ``` ### Arguments | Argument | Description | | ---------------- | ---------------------------------------------------------------------- | | `credentialType` | n8n credential type (e.g., `twilioApi`, `openAiApi`, `httpHeaderAuth`) | ### Options | Option | Description | Default | | ------------------ | ---------------------- | -------------- | | `--profile ` | CLI profile to use | Active profile | | `--api-key ` | Override API key | — | | `--json` | Output raw JSON schema | `false` | ### Examples ```bash theme={null} # See what fields twilioApi needs codika integration schema twilioApi # Output: # Credential type: twilioApi # Properties: # authType: string [authToken, apiKey] # accountSid: string # authToken: string # allowedDomains: string # Conditional rules: # if authType = authToken then require: authToken # if authType = apiKey then require: apiKeySid, apiKeySecret # Raw JSON (for automation) codika integration schema openAiApi --json ``` ### Use with custom integrations When you need a custom integration that maps to a specific n8n credential type (e.g., `twilioApi` instead of `httpHeaderAuth`), use `schema` to discover the required fields, then define your `n8nCredentialMapping` accordingly: ```bash theme={null} # 1. Check what fields n8n needs codika integration schema twilioApi # 2. Define custom integration in config.ts with those fields # n8nCredentialType: 'twilioApi' # n8nCredentialMapping: { ACCOUNT_SID: 'accountSid', AUTH_TOKEN: 'authToken', ... } ``` *** ## Common recipes ### Set up AI provider for an organization ```bash theme={null} codika integration set openai \ --secrets '{"OPENAI_API_KEY":"sk-proj-xxx"}' \ --json ``` ### Set up Supabase for a process instance ```bash theme={null} codika integration set supabase \ --secrets '{"SUPABASE_HOST":"https://abc.supabase.co","SUPABASE_SERVICE_ROLE_KEY":"eyJ..."}' \ --path ./my-use-case \ --json ``` ### Full deployment + integration flow ```bash theme={null} codika deploy use-case ./my-use-case --json codika integration set openai --secrets '{"OPENAI_API_KEY":"sk-xxx"}' --json codika integration set supabase \ --secrets '{"SUPABASE_HOST":"...","SUPABASE_SERVICE_ROLE_KEY":"..."}' \ --path ./my-use-case --json # Custom integrations — schema auto-extracted from config.ts codika integration set cstm_acme_crm \ --secrets '{"API_KEY":"acme_sk_xxx"}' \ --path ./my-use-case --json codika rerun deployment --path ./my-use-case --force --json ``` ## Authentication All integration commands require an API key with the `integrations:manage` scope. The standard authentication chain applies: 1. `--api-key` flag (highest priority) 2. `CODIKA_API_KEY` environment variable 3. Active profile from `codika login` ## Exit codes | Code | Meaning | | ---- | ------------------------------------------------------------------------ | | `0` | Success | | `1` | API error | | `2` | Validation error (missing fields, OAuth integration, unconfirmed delete) | # Manage Project Notes Source: https://doc.codika.io/operations/manage-project-notes Create, update, and read versioned project documents that persist across sessions ## When to use * Persist context about a project across sessions (briefs, known issues, changelogs) * Read what a previous session documented about a project * Track changes over time with full version history ## How it differs from metadata documents **Metadata documents** are deployment snapshots — frozen copies of config.ts and workflow JSON archived when you deploy. They cannot be updated after deployment. **Project notes** are living knowledge — updated any time, independently versioned, meant to accumulate context over the project's lifetime. Multiple agents can read and write the same project's documents across sessions. ## Prerequisites * `codika` CLI installed and authenticated * A project ID ## Commands ### Upsert a document Create a new document type or update an existing one. First call creates v0.0.0, subsequent calls increment the patch version. ```bash theme={null} codika notes upsert --type --summary [options] ``` ### List documents ```bash theme={null} codika notes list [--type ] [options] ``` ### Get a document ```bash theme={null} codika notes get --type [options] ``` ## Options ### Upsert options | Flag | Description | | --------------------- | -------------------------------------------------------- | | `--type ` | **(Required)** Document type ID (lowercase with hyphens) | | `--summary ` | **(Required)** What changed in this version | | `--title ` | Document title (defaults to type ID) | | `--content <content>` | Markdown content | | `--file <path>` | Read content from a file instead of `--content` | Content can also be piped via stdin: `echo "..." | codika notes upsert <projectId> --type <type> --summary "..."` \| `--agent-id <id>` | Agent identifier for tracking | \| `--major-change` | Bump minor version instead of patch | \| `--api-key <key>` | API key override | \| `--json` | JSON output | ### Get options | Flag | Description | | ---------------------------- | ------------------------------------- | | `--type <type>` | **(Required)** Document type ID | | `--target-version <version>` | Get a specific version (e.g. `0.1.0`) | | `--history` | Show all versions | | `--api-key <key>` | API key override | | `--json` | JSON output | ## What happens on upsert 1. If no document of that type exists for the project, creates version `0.0.0` 2. If a current version exists, increments patch (`0.0.0` -> `0.0.1`) 3. Marks the previous version as `superseded` (immutable, still queryable) 4. Updates the version history ## Versioning * **Patch** (default): `0.0.0` -> `0.0.1` -> `0.0.2` * **Minor** (`--major-change`): `0.0.5` -> `0.1.0` * Previous versions are never deleted — full history is preserved ## Examples **Record a project brief:** ```bash theme={null} codika notes upsert proj-abc123 \ --type brief \ --title "Project Brief" \ --content "This project automates invoice processing for SMBs..." \ --summary "Initial brief" ``` **Update from a file:** ```bash theme={null} codika notes upsert proj-abc123 \ --type known-issues \ --file ./notes/known-issues.md \ --summary "Added timeout issue" ``` **List all documents:** ```bash theme={null} codika notes list proj-abc123 ``` **Read a document:** ```bash theme={null} codika notes get proj-abc123 --type brief ``` **View version history:** ```bash theme={null} codika notes get proj-abc123 --type known-issues --history ``` ## Output **Upsert success:** ``` Created brief -> v0.0.0 Document ID: 019... Project: proj-abc123 ``` **List:** ``` Project notes for project proj-abc123: brief v0.0.0 "Project Brief" Initial brief (45 words) known-issues v0.0.3 "Known Issues" Added timeout issue (120 words) 2 document(s) ``` ## Suggested document types These are conventions, not enforced — use any lowercase-hyphenated name: | Type | Purpose | | ------------------ | ------------------------------------------------------- | | `brief` | What the project does, who it's for, key decisions | | `known-issues` | Bugs, edge cases, gotchas discovered during development | | `changelog` | What changed and why across deployments | | `debugging-log` | Diagnostic trail for ongoing issues | | `deployment-notes` | Current deployment state and configuration | | `architecture` | Key architectural decisions and rationale | ## Agent workflow patterns ### Start of session: read existing context ```bash theme={null} codika notes list $PROJECT_ID codika notes get $PROJECT_ID --type brief codika notes get $PROJECT_ID --type known-issues ``` ### After building/deploying: record what you did ```bash theme={null} codika notes upsert $PROJECT_ID --type changelog \ --content "v2: Added retry logic, increased timeout to 60s" \ --summary "v2 deployment" --agent-id "use-case-builder" ``` ### After debugging: document the fix ```bash theme={null} codika notes upsert $PROJECT_ID --type debugging-log \ --content "Timeout on large PDFs. Root cause: token limit. Fix: chunking." \ --summary "Fixed PDF timeout" ``` ### Diagnosing issues: check history ```bash theme={null} codika notes get $PROJECT_ID --type changelog --history ``` ## Error handling | Error | Cause | Fix | | ---------------------------------------------- | ------------------- | ------------------------------------- | | "API key is required" | Not authenticated | Run `codika login` | | "Project not found" | Invalid project ID | Verify with `codika get project <id>` | | "documentTypeId must be lowercase" | Invalid type format | Use lowercase with hyphens | | "content is required" | Missing content | Provide `--content` or `--file` | | "content must be less than 500,000 characters" | Content too large | Split into multiple documents | ## Exit codes | Code | Meaning | | ---- | ------- | | `0` | Success | | `1` | Failure | # Operations Reference Source: https://doc.codika.io/operations/overview Complete reference for all Codika platform operations — authentication, scaffolding, validation, deployment, execution, and debugging ## Overview This reference covers every operation available on the Codika platform. Each page documents the **what**, **when**, **how** (CLI command + all flags), and **why** for a single capability. Operations are grouped by lifecycle phase. The `codika` CLI (`npm install -g codika`) is the primary interface for all operations. Requires Node.js 22+. ## Operations by lifecycle phase ### Setup | Operation | CLI command | What it does | | -------------------------------------------------------------- | -------------------------------------------- | ---------------------------------------------------------------- | | [Authentication](/operations/authentication) | `login`, `whoami`, `use`, `logout`, `config` | Install CLI, authenticate, manage profiles, switch organizations | | [Create Project](/operations/create-project) | `project create` | Create a platform project and link it to a use case folder | | [Create Organization](/operations/create-organization) | `organization create` | Create a new organization | | [Create Organization Key](/operations/create-organization-key) | `organization create-key` | Create an API key for an organization | | [Update Organization Key](/operations/update-organization-key) | `organization update-key` | Update scopes, name, or description of an API key | ### Build | Operation | CLI command | What it does | | ------------------------------------------------ | ------------------------------------ | ----------------------------------------------------------------------- | | [Initialize Use Case](/operations/init-use-case) | `init <path>` | Scaffold a new use case folder with template workflows and agent skills | | [Verify Use Case](/operations/verify-use-case) | `verify use-case`, `verify workflow` | Validate use cases against structural and semantic rules | ### Deploy | Operation | CLI command | What it does | | ---------------------------------------------------------- | -------------------------------------- | --------------------------------------------------------------- | | [Deploy Use Case](/operations/deploy-use-case) | `deploy use-case <path>` | Deploy workflows to the platform with version management | | [Deploy Data Ingestion](/operations/deploy-data-ingestion) | `deploy process-data-ingestion <path>` | Deploy RAG/embedding pipeline configuration | | [Deploy Documents](/operations/deploy-documents) | `deploy documents <path>` | Upload stage documentation to the platform | | [Publish Use Case](/operations/publish-use-case) | `publish <templateId>` | Promote a deployment from dev to production | | [Rerun Deployment](/operations/rerun-deployment) | `rerun deployment` | Update parameters on an existing instance without a new version | ### Operate | Operation | CLI command | What it does | | --------------------------------------------------------------- | ------------------------------------------- | ---------------------------------------------------------------- | | [Trigger Workflow](/operations/trigger-workflow) | `trigger <workflowId>` | Execute a deployed workflow via HTTP | | [Fetch Use Case](/operations/fetch-use-case) | `get use-case <projectId>` | Download a deployed use case from the platform | | [Get Execution](/operations/get-execution) | `get execution <executionId>` | Debug executions with node-level details | | [Get Instance](/operations/get-instance) | `get instance [instanceId]` | Inspect a live instance — parameters, status, version, workflows | | [Activate / Deactivate Instance](/operations/instance-activate) | `instance activate/deactivate [instanceId]` | Activate or deactivate a process instance | | [List Executions](/operations/list-executions) | `list executions <instanceId>` | List recent executions for a process instance | | [List Instances](/operations/list-instances) | `list instances` | List all process instances for an organization | | [List Projects](/operations/list-projects) | `list projects` | List all projects for an organization | | [Get Project](/operations/get-project) | `get project <projectId>` | Inspect project details — status, deployment, stages | | [Get Skills](/operations/get-skills) | `get skills [instanceId]` | Download agent skill documents from a deployed process | | [Manage Integrations](/operations/manage-integrations) | `integration set/list/delete` | Configure API keys and credentials for organizations | | [Status](/operations/status) | `status [path]` | Check identity, context, and deployment readiness | ## CLI global configuration Configuration is stored at `~/.config/codika/config.json` (XDG-compliant, permissions `0o600`). The CLI supports **multiple named profiles**, each containing: | Field | Description | | ----------- | ---------------------------------------------------------------- | | `apiKey` | The Codika API key (prefix `cko_`) | | `baseUrl` | Platform API URL | | `orgId` | Organization ID | | `orgName` | Organization display name | | `keyName` | API key display name | | `scopes` | Permission scopes (e.g., `deploy:use-case`, `workflows:trigger`) | | `createdAt` | When the key was created | | `expiresAt` | When the key expires | ## Resolution chains The CLI resolves values in a predictable priority order. Higher-priority sources override lower ones. ### API key resolution 1. `--api-key` flag (highest priority) 2. `CODIKA_API_KEY` environment variable 3. Active profile in config file 4. Error if none found ### Base URL resolution 1. `--api-url` flag 2. `CODIKA_API_URL` environment variable (or per-endpoint vars like `CODIKA_DEPLOY_API_URL`) 3. Active profile base URL 4. Production default ### Project ID resolution 1. `--project-id` flag 2. `project.json` at `--project-file` path (if provided) 3. `project.json` in use case folder 4. `PROJECT_ID` export in `config.ts` ### Organization-aware profile selection When `project.json` contains an `organizationId`, the CLI automatically selects the profile that matches that organization — even if a different profile is currently active. This is especially important for deployment commands. The selection order: 1. `--api-key` flag (always wins) 2. `CODIKA_API_KEY` environment variable 3. Profile matching `organizationId` from `project.json` 4. Active profile ## Global options These options work across most commands: | Option | Description | | ----------------------- | ----------------------------------------------------- | | `--json` | Output as machine-readable JSON | | `--api-key <key>` | Override API key | | `--api-url <url>` | Override API base URL | | `--project-file <path>` | Path to custom project file (default: `project.json`) | | `--profile <name>` | Use a specific profile instead of the active one | ## Global exit codes | Code | Meaning | | ---- | ------------------------------------------------------------------ | | `0` | Success | | `1` | Runtime error (API failure, missing files, etc.) | | `2` | CLI validation error (invalid arguments, missing required options) | ## Profile expiry warnings On every command, the CLI checks the active profile's key expiry: * **\< 7 days until expiry**: Displays a warning * **Expired**: Displays an error * **No expiry data**: No warning ## Typical workflow An agent or human orchestrating a full deployment uses operations in this order: ``` 1. authentication → Verify CLI installed and authenticated 2. create-project → Create platform project (if needed) 3. init-use-case → Scaffold the use case folder 4. (Build config.ts and workflows) 5. verify-use-case → Validate before deploying 6. deploy-use-case → Deploy to platform (dev) 6b. deploy-data-ingestion → Deploy DI config (if RAG use case) 6c. deploy-documents → Upload stage documents 7. trigger-workflow → Test the deployment 8. get-execution → Debug if needed 9. list-executions → Review recent execution history 10. publish-use-case → Publish to production when ready 11. rerun-deployment → Update parameters without new version 12. get-instance → Inspect live instance (parameters, status, version) 13. instance activate → Activate or deactivate instances 14. list instances → List all process instances for the org 15. manage-integrations → Configure required API keys/credentials ``` ## Command hierarchy ``` codika ├── login # Save API key (alias for config set) ├── logout [name] # Remove a profile ├── whoami # Show current identity ├── use [name] # Switch active profile or list profiles ├── status [path] # Show identity and use case context ├── init <path> # Scaffold a new use case ├── config │ ├── set # Save API key and base URL │ ├── show # Display all profiles │ └── clear # Remove configuration ├── verify │ ├── use-case <path> # Validate entire use case folder │ └── workflow <path> # Validate single workflow file ├── deploy │ ├── use-case <path> # Deploy use case to platform │ ├── process-data-ingestion <path> # Deploy data ingestion config │ └── documents <path> # Upload stage documentation ├── publish <templateId> # Publish deployment to production ├── rerun deployment # Rerun deployment with updated parameters ├── integration │ ├── set <integrationId> # Create or update an integration │ ├── list # List integrations and connection status │ └── delete <integrationId> # Delete an integration ├── trigger <workflowId> # Trigger a deployed workflow ├── get │ ├── use-case <projectId> # Fetch deployed use case │ ├── execution <executionId> # Fetch execution details │ ├── instance [instanceId] # Inspect live instance details │ ├── project <projectId> # Inspect project details │ └── skills [instanceId] # Fetch agent skill documents ├── instance │ ├── activate [instanceId] # Activate a process instance │ └── deactivate [instanceId] # Deactivate a process instance ├── list │ ├── executions <instanceId> # List recent executions │ ├── instances # List all process instances │ └── projects # List all projects ├── project │ └── create # Create a new project ├── organization │ ├── create # Create a new organization │ ├── create-key # Create an organization API key │ └── update-key # Update an organization API key └── completion [shell] # Generate shell completions ``` # Publish Use Case Source: https://doc.codika.io/operations/publish-use-case Promote a deployed use case from dev to production, set visibility and sharing, and manage dev/prod instance toggling ## When to use * Promote a deployed use case from dev to production * Make a process available to end users for the first time * Configure visibility (private, organizational, public) on first publish * Enable dev/prod auto-toggle to pause dev when prod is running ## Prerequisites * `codika` CLI installed and authenticated * A deployed use case with `project.json` containing a `deployments` map (run `deploy use-case` first) * API key with `deploy:use-case` scope ## Command ```bash theme={null} codika publish <templateId> [options] ``` ## Arguments | Argument | Description | | -------------- | ------------------------------------------------------------ | | `<templateId>` | Deployment template ID (from `project.json` deployments map) | ## Options | Option | Description | Default | | ------------------------ | ------------------------------------------------------------- | ----------------------------- | | `--path <path>` | Path to use case folder with project.json | Current directory | | `--project-file <path>` | Custom project file path | `project.json` | | `--project-id <id>` | Override project ID | `project.json` | | `--visibility <scope>` | `private`, `organizational`, or `public` (first publish only) | — | | `--shared-with <scope>` | `owner_only`, `admins`, or `everyone` (org processes only) | — | | `--auto-toggle-dev-prod` | Pause dev instance when prod is active | Off (both run simultaneously) | | `--skip-prod-instance` | Don't auto-create/update prod instance | — | | `--api-url <url>` | Override API URL | — | | `--api-key <key>` | Override API key | — | | `--profile <name>` | Use a specific profile instead of the active one | — | | `--json` | JSON output | — | ## Finding the template ID After each deploy, `project.json` stores a `deployments` map keyed by version: ```json theme={null} { "projectId": "abc123", "devProcessInstanceId": "pi_dev_456", "deployments": { "1.0": { "templateId": "tmpl_abc", "createdAt": "2026-03-04T14:30:00Z" }, "1.1": { "templateId": "tmpl_def", "createdAt": "2026-03-04T15:00:00Z" } } } ``` Use the `templateId` from the version you want to publish. ## What happens on publish 1. **Resolve** project ID: `--project-id` > `--project-file` > `project.json` 2. **Resolve** API key: `--api-key` > env > active profile 3. **Send** publish request to platform with templateId, projectId, and options 4. **Platform** publishes the deployment template (status: inactive → published) 5. **Platform** deprecates any previously published templates for this project 6. **Platform** auto-creates or updates the owner's prod process instance 7. If `--auto-toggle-dev-prod`, deactivates dev instance 8. **On success:** saves `prodProcessInstanceId` to `project.json` ## Visibility Set on first publish only. Subsequent publishes inherit the existing visibility. | Level | Who can see and install | | ---------------- | ----------------------- | | `private` | Only the owner | | `organizational` | All org members | | `public` | Anyone on the platform | ## Shared with Controls who can use the prod instance. Applies to organizational processes only. | Scope | Who can use the prod instance | | ------------ | ----------------------------------------------- | | `owner_only` | Only the process owner | | `admins` | Organization admins (default for org processes) | | `everyone` | All organization members | ## Dev/Prod toggle By default, both dev and prod instances run simultaneously. Use `--auto-toggle-dev-prod` to pause the dev instance when production becomes active: ```bash theme={null} codika publish tmpl_abc123 --auto-toggle-dev-prod ``` This keeps production as the single active instance, avoiding duplicate executions from scheduled or webhook triggers. To disable the toggle after publishing, re-publish without the flag or update the setting in the platform UI. ## Examples ```bash theme={null} # Publish the latest deployment codika publish tmpl_abc123 # Publish with visibility (first publish) codika publish tmpl_abc123 --visibility organizational --shared-with admins # Publish from a specific directory codika publish tmpl_abc123 --path ./my-use-case # JSON output codika publish tmpl_abc123 --json # Pause dev when prod runs codika publish tmpl_abc123 --auto-toggle-dev-prod ``` ## Output ``` ✓ Published successfully! Version: 1.1 Template ID: tmpl_abc123 Prod Instance ID: pi_prod_789 Webhook URL: https://... ``` <Info> **Need to change parameters without a new version?** After publishing, use [`codika rerun deployment`](/operations/rerun-deployment) to update deployment parameters on the prod instance without creating a new template version. Only the parameters you specify are changed — everything else stays the same. </Info> ## Error reference | HTTP | Error | Fix | | ---- | ------------------ | --------------------------------------------------- | | 401 | Invalid API key | Re-login with `codika login` | | 403 | Missing scope | Create key with `deploy:use-case` scope | | 404 | Template not found | Check templateId in project.json deployments | | 400 | Invalid status | Template already published or not in inactive state | ## Exit codes | Code | Meaning | | ---- | -------------------------------------------------------- | | `0` | Publish successful | | `1` | API error | | `2` | CLI validation error (missing templateId, no project ID) | # Rerun Deployment Source: https://doc.codika.io/operations/rerun-deployment Rerun an existing deployment with refreshed credentials and updated parameters, without creating a new template version ## When to use * Change deployment parameters on a running instance (e.g., company name, language, timezone) * Retry a failed deployment without creating a new template version * Apply credential or configuration changes after publishing without bumping the version <Info> **This command does NOT upload local code changes.** If you edited `config.ts` or any file under `workflows/`, use [`codika deploy use-case`](/operations/deploy-use-case) instead. `rerun deployment` only re-runs the existing remote template with refreshed credentials and optional parameter overrides. </Info> ## Prerequisites * `codika` CLI installed and authenticated * An existing deployment with `project.json` containing `devProcessInstanceId` or `prodProcessInstanceId` * API key with `deploy:use-case` scope ## Command ```bash theme={null} codika rerun deployment [options] ``` ## Options | Option | Description | Default | | ---------------------------- | ------------------------------------------------ | ----------------- | | `--process-instance-id <id>` | Target process instance ID | — | | `--path <path>` | Path to use case folder with `project.json` | Current directory | | `--project-file <path>` | Path to custom project file | `project.json` | | `--environment <env>` | Target environment (`dev` or `prod`) | `dev` | | `--param <KEY=VALUE>` | Set a single parameter (repeatable) | — | | `--params <json>` | JSON string with parameters | — | | `--params-file <path>` | Path to JSON file with parameters | — | | `--force` | Force rerun on non-failed instances | `false` | | `--profile <name>` | Use a specific profile instead of the active one | — | | `--api-url <url>` | Override API URL | — | | `--api-key <key>` | Override API key | — | | `--json` | JSON output | `false` | ## Process instance resolution The CLI resolves which process instance to rerun using this priority: 1. `--process-instance-id` flag (highest priority) 2. `project.json` field based on `--environment`: * `dev` → `devProcessInstanceId` * `prod` → `prodProcessInstanceId` If neither is found, the command exits with an error. ## Parameter input methods You can provide parameters in three ways. When multiple methods are used, they are merged with this priority (highest wins): 1. `--param KEY=VALUE` flags (repeatable, highest priority) 2. `--params '{"key": "value"}'` JSON string 3. `--params-file ./params.json` JSON file (lowest priority) <Info> **Parameters are merged, not replaced.** The CLI sends only the parameters you provide. The platform merges them with the instance's existing parameters. If the instance has `COMPANY_NAME=Acme` and `LANGUAGE=en`, and you pass `--param LANGUAGE=fr`, the result is `COMPANY_NAME=Acme` and `LANGUAGE=fr`. Omitted parameters keep their current values. </Info> ## What happens on rerun 1. **Load** the target process instance from the platform 2. **Load** the deployment template currently associated with the instance 3. **Merge** provided parameters with existing instance parameters 4. **Refresh** workflows — re-run placeholder replacement with updated parameters and current credential state 5. **Deploy** updated workflows to n8n in-place (preserving existing `n8nWorkflowId` so webhook URLs stay stable) The instance owner's credentials are used for deployment, not the API key user's. This ensures workflows are deployed with the correct integration bindings. <Warning> Rerunning does **not** create a new template version. The instance continues to run the same template — only the runtime parameters and credentials are refreshed. To deploy new workflow logic, use [`codika deploy use-case`](/operations/deploy-use-case) instead. </Warning> ## Force flag | Instance status | `--force` required? | | --------------- | ------------------------------------------- | | `failed` | No — failed instances can always be retried | | `deployed` | Yes | | `deploying` | Yes | | `user_paused` | Yes | ## Agent usage When automating reruns, prefer `--params` with JSON and `--json` for structured output: ```bash theme={null} codika rerun deployment --params '{"COMPANY_NAME":"New Corp","LANGUAGE":"fr"}' --json ``` This avoids shell escaping issues with `--param` and provides machine-readable output. ## Examples ```bash theme={null} # Change a single parameter codika rerun deployment --param COMPANY_NAME="New Corp" # Multiple parameters (human-friendly) codika rerun deployment \ --param COMPANY_NAME="New Corp" \ --param LANGUAGE=fr \ --param TIMEZONE="Europe/Paris" # Agent-friendly JSON codika rerun deployment --params '{"COMPANY_NAME":"New Corp","LANGUAGE":"fr"}' # From file codika rerun deployment --params-file ./updated-params.json # Retry a failed deployment (no --force needed) codika rerun deployment --environment dev # Rerun prod deployment codika rerun deployment --environment prod --param LANGUAGE=fr --force # Custom project file codika rerun deployment --project-file project-client-a.json --param LANGUAGE=fr # Specific instance ID codika rerun deployment --process-instance-id pi_abc123 --param LANGUAGE=fr --force # JSON output for automation codika rerun deployment --params '{"LANGUAGE":"fr"}' --json ``` ## Output ``` ✓ Deployment rerun successfully Instance: pi_abc123 Environment: dev Template: tmpl_def456 Parameters: 2 updated, 3 unchanged ``` JSON output (`--json`): ```json theme={null} { "success": true, "processInstanceId": "pi_abc123", "environment": "dev", "templateId": "tmpl_def456", "parameters": { "updated": ["COMPANY_NAME", "LANGUAGE"], "unchanged": ["TIMEZONE", "REPORT_EMAIL", "MAX_RETRIES"] } } ``` ## Error reference | HTTP | Error | Fix | | ---- | ---------------------------- | ------------------------------------------------------------------- | | 401 | Invalid API key | Re-login with `codika login` | | 403 | Missing scope | Create key with `deploy:use-case` scope | | 404 | Instance not found | Check instance ID in `project.json` or pass `--process-instance-id` | | 409 | Instance not in failed state | Add `--force` to rerun non-failed instances | | 400 | Invalid parameters | Check parameter names match `INSTPARM` placeholders in the template | ## Exit codes | Code | Meaning | | ---- | ------------------------------ | | `0` | Rerun successful | | `1` | Deployment failed or API error | # Status Source: https://doc.codika.io/operations/status Check identity, use case context detection, profile match status, and deployment readiness ## When to use * Quick health check before deploying * Verify you're authenticated to the right organization * Check if a use case folder is ready to deploy * Diagnose profile mismatches between your active profile and the project's org ## Prerequisites * `codika` CLI installed (authentication is checked but not required) ## Command ```bash theme={null} codika status [path] [options] ``` ## Arguments | Argument | Description | | -------- | --------------------------------------------- | | `[path]` | Path to check (defaults to current directory) | ## Options | Option | Description | | ----------------------- | ----------------------------------------------------- | | `--json` | Output as JSON | | `--project-file <path>` | Path to custom project file (default: `project.json`) | | `--verify` | Run quick validation on the detected use case | ## Output sections ### Identity Shows the current authenticated state: ``` Identity: Status: Logged in Organization: Acme Corp Profile: acme-corp Key: cko_abc...xyz ``` ### Use case context If a use case folder is detected at the path: ``` Use Case: Detected: ✓ Title: Email Automation Version: 1.2.3 Workflows: 3 Project ID: abc123 Profile: ✓ match (acme-corp) ``` ### Profile match status | Status | Meaning | | ------------------- | ----------------------------------------------------------------- | | `match` | Active profile's org matches `project.json` org — ready to deploy | | `mismatch` | Different org — shows suggested profile to switch to | | `no-org-in-project` | No `organizationId` in `project.json` | | `no-profile` | Not logged in | ### Readiness Shows whether the use case is ready to deploy: ``` Readiness: ✓ Ready to deploy ``` Or with issues: ``` Readiness: ✗ Not ready to deploy - No project.json found - Profile org does not match project org (try: codika use staging) ``` ### Warnings * **Profile mismatch**: "Active profile 'acme-corp' does not match project org. Suggested: 'staging'" * **Key expiry \< 7 days**: "API key expires in 3 days" * **Key expired**: "API key has expired" ## Examples ```bash theme={null} # Check status in current directory codika status # Check a specific directory codika status ./email-automation # Check with validation codika status ./email-automation --verify # Machine-readable output codika status --json ``` ## Exit codes | Code | Meaning | | ---- | ------------------------ | | `0` | Ready to deploy | | `1` | Not ready (issues found) | # Trigger Workflow Source: https://doc.codika.io/operations/trigger-workflow Execute a deployed workflow (HTTP or scheduled) via the CLI, with payload support, polling for results, and process instance ID resolution ## When to use * Test a deployed workflow * Execute a workflow via the CLI instead of the platform UI * Automate workflow execution in scripts or CI ## Prerequisites * Use case deployed (`project.json` contains `devProcessInstanceId`) * Authenticated via `codika login` or `CODIKA_API_KEY` env var * API key with `workflows:trigger` scope ## Resolving the workflow ID The `workflowId` is the `workflowTemplateId` from `config.ts`. If the user provides a use case folder path, read `config.ts` to find the available workflow IDs and their trigger types. **Supported trigger types:** * **HTTP triggers** (`trigger.type === 'http'`): Triggered with optional payload * **Schedule triggers** (`trigger.type === 'schedule'`): Triggered via the `manualTriggerUrl` configured in `config.ts`. The CLI creates an execution document upfront and passes it to the workflow, so `--poll` works exactly like HTTP triggers. No payload is needed. ## Command ```bash theme={null} codika trigger <workflowId> [options] ``` ## Arguments | Argument | Description | | -------------- | --------------------------------------- | | `<workflowId>` | The `workflowTemplateId` from config.ts | ## Options | Option | Description | Default | | ---------------------------- | ----------------------------------------------------------- | --------------------------------- | | `--process-instance-id <id>` | Explicit process instance ID | Auto-resolved from `project.json` | | `--project-file <path>` | Path to custom project file (e.g., `project-client-a.json`) | `project.json` | | `--path <path>` | Path to use case folder with `project.json` | Current directory | | `--payload-file <path>` | Read payload from a JSON file, or `-` for stdin | — | | `--poll` | Wait for execution to complete | Fire-and-forget | | `--timeout <seconds>` | Max poll time | `120` | | `-o, --output <path>` | Save result to file (with `--poll`) | stdout | | `--api-url <url>` | Override API URL | — | | `--api-key <key>` | Override API key | — | | `--profile <name>` | Use a specific profile instead of the active one | — | | `--json` | JSON output | — | ## Process instance ID resolution 1. `--process-instance-id` flag (highest priority) 2. `devProcessInstanceId` in `--project-file` (if provided) 3. `devProcessInstanceId` in `project.json` at `--path` 4. `devProcessInstanceId` in `project.json` in current directory ## Behavior ### Fire-and-forget (default) Returns immediately with the execution ID: ```bash theme={null} codika trigger main-workflow ``` ``` ✓ Workflow triggered Execution ID: exec_abc123 Process Instance: pi_def456 Workflow: main-workflow Poll for status: codika get execution exec_abc123 ``` ### Poll for results (`--poll`) Waits for the execution to complete, polling every 3-5 seconds: ```bash theme={null} codika trigger main-workflow --poll --payload-file - <<'EOF' {"query": "test"} EOF ``` ``` ✓ Workflow triggered (execution: exec_abc123) ✓ Execution success (2.3s) Result: { "summary": "Analysis complete", "confidence": 95 } Execution ID: exec_abc123 ``` ### Payload via stdin (recommended) Use `--payload-file -` with a heredoc to pass JSON without shell escaping issues: ```bash theme={null} codika trigger main-workflow --poll --payload-file - <<'EOF' {"query": "machine learning", "maxResults": 10} EOF ``` This is the recommended approach when calling from scripts or AI agents, as it avoids shell quoting problems with nested JSON. ### Payload from file ```bash theme={null} codika trigger main-workflow --payload-file ./test-input.json --poll ``` The file must contain a JSON object. ### Save result to file ```bash theme={null} codika trigger main-workflow --poll -o ./result.json --payload-file - <<'EOF' {"query": "test"} EOF ``` ## Result statuses | Status | Meaning | Data field | | --------- | ---------------------------------------- | ---------------------------------------- | | `success` | Workflow completed successfully | `resultData` contains output | | `failed` | Workflow encountered an error | `errorDetails.message` describes failure | | `pending` | Still running (only seen during polling) | — | ## Examples ```bash theme={null} # Trigger with heredoc payload and poll codika trigger search --poll --payload-file - <<'EOF' {"query": "machine learning"} EOF # Trigger with payload file and poll codika trigger analyze \ --payload-file input.json \ --poll \ --timeout 300 # Trigger from a different directory codika trigger main-workflow \ --path ./my-use-case \ --poll --payload-file - <<'EOF' {"text": "hello"} EOF # Explicit process instance ID codika trigger main-workflow \ --process-instance-id pi_abc123 \ --poll --payload-file - <<'EOF' {"text": "hello"} EOF # JSON output for scripting codika trigger main-workflow \ --poll \ --json \ --payload-file - <<'EOF' {"text": "test"} EOF # Trigger a scheduled workflow manually (no payload needed) codika trigger daily-report --poll ``` ## Error reference | HTTP | Error | Cause | Fix | | ---- | ------------------ | ----------------------------- | ------------------------------------ | | 401 | Invalid API key | Wrong or expired key | `codika whoami`, then `codika login` | | 403 | Missing scope | Key lacks `workflows:trigger` | Create new key with scope | | 403 | No access | Process in different org | `codika use <profile>` | | 404 | Workflow not found | Wrong workflowId | Check `config.ts` workflowTemplateId | | 412 | Instance inactive | Process paused or failed | Re-deploy or check platform | ## Important notes * Both HTTP and schedule triggers are supported * Schedule triggers require a `manualTriggerUrl` in config.ts (with a matching Webhook node in the workflow JSON) * The `workflowId` is the `workflowTemplateId` from config.ts, not the n8n workflow ID * For HTTP triggers: the request wraps your payload in `{"payload": {...}}` * For schedule triggers: no payload needed (the workflow runs its own logic) * Execution is asynchronous — the trigger returns immediately unless `--poll` is used * `--poll` works for both trigger types * File uploads are not supported via CLI — use the platform UI # Update Organization Key Source: https://doc.codika.io/operations/update-organization-key Update the scopes, name, or description of an existing organization API key ## When to use * Change the scopes of an existing API key (e.g., add `projects:read` scope) * Rename a key for better identification * Update the description of a key ## Prerequisites * `codika` CLI installed and authenticated * API key with `api-keys:manage` scope * Caller must be an admin or owner in the organization * The key ID of the key to update (from the platform dashboard or `create-key` output) ## Command ```bash theme={null} codika organization update-key [options] ``` ## Options | Option | Description | Default | | ---------------------- | ------------------------------------------------ | ------- | | `--key-id <id>` | Key ID to update (required) | — | | `--scopes <scopes>` | New comma-separated scopes (replaces existing) | — | | `--name <name>` | New key name | — | | `--description <desc>` | New key description | — | | `--api-url <url>` | Override API URL | — | | `--api-key <key>` | Override API key | — | | `--profile <name>` | Use a specific profile instead of the active one | — | | `--json` | Output as JSON | — | <Info> At least one of `--scopes`, `--name`, or `--description` must be provided. When `--scopes` is provided, it **replaces** the existing scopes entirely. </Info> ## Available scopes | Scope | Description | | --------------------- | ----------------------------------------------------- | | `deploy:use-case` | Deploy use cases, upload documents, and read metadata | | `projects:create` | Create new projects via API | | `projects:read` | List and inspect project details | | `workflows:trigger` | Trigger workflows and poll execution status | | `executions:read` | List and read execution details | | `instances:read` | Read process instance details | | `instances:manage` | Activate, deactivate, and manage instances | | `skills:read` | Download agent skill documents | | `integrations:manage` | Create, delete, and list integrations | | `api-keys:manage` | Create and manage organization API keys | ## Examples ```bash theme={null} # Update scopes codika organization update-key --key-id abc123 --scopes deploy:use-case,instances:read,projects:read # Rename a key codika organization update-key --key-id abc123 --name "Production Deploy Key" # Update description codika organization update-key --key-id abc123 --description "Used by CI/CD pipeline" # Multiple fields at once codika organization update-key --key-id abc123 --name "Full Access" --scopes deploy:use-case,instances:read,instances:manage # JSON output codika organization update-key --key-id abc123 --scopes deploy:use-case --json ``` ## Output ### Human-readable (default) ``` ✓ API key updated Key ID: abc123 Name: Production Deploy Key Scopes: deploy:use-case, instances:read, projects:read ``` ### JSON output (`--json`) ```json theme={null} { "success": true, "data": { "keyId": "abc123", "name": "Production Deploy Key", "description": "Used by CI/CD pipeline", "scopes": ["deploy:use-case", "instances:read", "projects:read"], "updatedAt": "2026-03-31T14:00:00.000Z" }, "requestId": "019d312f-..." } ``` ## Exit codes | Code | Meaning | | ---- | ------------------------------------------------------------------- | | `0` | Success | | `1` | API error (key not found, insufficient permissions, invalid scopes) | | `2` | CLI validation error (missing key ID, missing API key) | # Verify Use Case Source: https://doc.codika.io/operations/verify-use-case Validate use case folders and individual workflow files against structural and semantic rules, with auto-fix support ## When to use * Before deploying to catch issues early * After modifying workflow JSON files * When the user asks to lint, validate, or check a use case * As part of a CI pipeline ## Prerequisites * `codika` CLI installed (**no authentication needed** — validation runs entirely locally) ## Commands ```bash theme={null} # Validate an entire use case folder codika verify use-case <path> [options] # Validate a single workflow file codika verify workflow <path> [options] ``` ## Options | Option | Description | | ----------------------- | ------------------------------------------------------------- | | `--json` | Machine-readable JSON output | | `--strict` | Treat `should` severity findings as `must` (fail on warnings) | | `--fix` | Auto-fix fixable violations in place | | `--dry-run` | Show what `--fix` would change without modifying files | | `--rules <ids>` | Run only these rules (comma-separated) | | `--exclude-rules <ids>` | Skip these rules (comma-separated) | ## Validation layers The validator runs four layers of checks, from low-level to high-level: ### Layer 1: Flowlint core rules Static analysis rules that check graph connectivity and basic workflow structure. | Rule | Severity | What it checks | | ------ | -------- | --------------------------- | | R1 | must | No disconnected nodes | | R5-R11 | varies | Various connectivity rules | | R13 | should | Error handling completeness | Rules R3 (idempotency guard) and R12 are excluded by default (replaced by custom Codika rules). ### Layer 2: Custom Codika rules Graph-based checks specific to Codika patterns. | Rule | Severity | What it checks | | ------------------------- | -------- | ------------------------------------------------- | | `CK-INIT` | must | Every parent workflow has a Codika Init node | | `CK-SUBMIT` | must | Success paths end with Codika Submit Result | | `CK-ERROR` | must | Error paths end with Codika Report Error | | `CK-SCHEDULE-CONVERGENCE` | must | Schedule/webhook triggers converge at Codika Init | | `CK-SUBWORKFLOW-PARAMS` | should | Sub-workflows have at least 1 input parameter | ### Layer 3: Workflow scripts Content-based checks that inspect workflow JSON values. | Rule | Severity | What it checks | Auto-fixable | | --------------------- | -------- | ------------------------------------------------------------------- | ------------ | | `CK-PLACEHOLDERS` | must | Placeholder syntax follows `{{TYPE_KEY_SUFFIX}}` pattern | No | | `CK-CREDENTIALS` | must | Credentials use Codika placeholder patterns | No | | `WF-WEBHOOK-ID` | should | Webhook IDs use correct placeholders | No | | `WF-LLM-OUTPUT` | should | LLM output node access patterns are correct | No | | `WF-LLM-MODEL` | should | LLM model IDs are valid | No | | `WF-INSTPARM-QUOTING` | should | INSTPARM placeholders not double-quoted | No | | `WF-SANITIZATION` | must | No transient IDs (versionId, meta, active, etc.) | Yes | | `WF-SETTINGS` | must | Required settings present (executionOrder, errorWorkflow, timezone) | Yes | ### Layer 4: Use-case scripts (use-case command only) Folder-level checks that validate the use case as a whole. | Rule | Severity | What it checks | | ------------------------ | -------- | -------------------------------------------------------------------------- | | `UC-TRIGGERS` | must | At least one trigger defined | | `UC-CONFIG-EXPORTS` | must | config.ts exports required members (WORKFLOW\_FILES, getConfiguration) | | `UC-WORKFLOW-IMPORTS` | must | All workflows referenced in config are present as files | | `UC-SUBWORKFLOW-REFS` | must | Sub-workflow SUBWKFL references are valid | | `UC-TRIGGER-CONSISTENCY` | should | Trigger types match workflow definitions | | `UC-WEBHOOK-PATHS` | should | Webhook paths are unique per workflow | | `UC-CALLEDBY` | should | calledBy arrays are consistent with actual usage | | `UC-SCHEMA-TYPES` | should | Input/output schema field types are valid | | `UC-INTEGRATIONS` | should | Integration UIDs are properly inherited | | `SKILL-STRUCTURE` | must | Every subdirectory in `skills/` contains a `SKILL.md` file | | `SKILL-NAME-FORMAT` | must | Skill `name` is max 64 chars, lowercase+numbers+hyphens, no reserved words | | `SKILL-DESCRIPTION` | should | Skill `description` is non-empty, max 1024 chars | | `SKILL-WORKFLOW-REF` | must | Skill `workflowTemplateId` matches an existing workflow file | | `SKILL-DUPLICATE` | must | No duplicate skill names or workflowTemplateIds | ## Output ### Text mode (default) ``` ✓ Use case validation passed must: 0 should: 0 nit: 0 ``` Or with findings: ``` ✗ Use case validation failed workflows/main-workflow.json: ✗ [CK-INIT] must: Parent workflow must have Codika Init node ⚠ [WF-SETTINGS] must: Missing required setting: errorWorkflow (fixable) config.ts: ⚠ [UC-SCHEMA-TYPES] should: Unknown field type "textarea" in input schema must: 1 should: 1 nit: 0 ``` ### JSON mode (`--json`) ```json theme={null} { "valid": false, "findings": [ { "rule": "CK-INIT", "severity": "must", "message": "Parent workflow must have Codika Init node", "path": "workflows/main-workflow.json", "nodeId": null, "fixable": false } ], "summary": { "must": 1, "should": 0, "nit": 0 } } ``` ## Recommended workflow ```bash theme={null} # 1. Run verification to see all issues codika verify use-case ./my-use-case # 2. Auto-fix what you can codika verify use-case ./my-use-case --fix # 3. Manually fix remaining "must" violations # 4. Verify again to confirm clean codika verify use-case ./my-use-case # 5. Deploy codika deploy use-case ./my-use-case ``` ## Examples ```bash theme={null} # Validate and auto-fix codika verify use-case ./email-automation --fix # Strict mode (warnings become errors) codika verify use-case ./email-automation --strict # Run only specific rules codika verify use-case ./email-automation --rules CK-INIT,CK-SUBMIT # Exclude rules codika verify use-case ./email-automation --exclude-rules WF-LLM-MODEL # Preview fixes without applying codika verify use-case ./email-automation --fix --dry-run # Validate a single workflow codika verify workflow ./email-automation/workflows/main.json # JSON output for CI pipelines codika verify use-case ./email-automation --json ``` ## Exit codes | Code | Meaning | | ---- | ------------------------- | | `0` | All validations passed | | `1` | Validation failures found | # Quickstart Source: https://doc.codika.io/quickstart Get started in 7 steps — install codika, authenticate, scaffold a use case, validate, deploy, trigger, and debug ## Prerequisites * Node.js 22 or higher * npm * A Codika API key (obtain from the Codika dashboard under Organization Settings > API Keys) ## Step 1: Install the CLI ```bash theme={null} npm install -g codika ``` Verify the installation: ```bash theme={null} codika --version ``` ## Step 2: Authenticate ```bash theme={null} codika login ``` This prompts for your API key (masked input), verifies it against the platform, and stores a named profile in `~/.config/codika/config.json`. For non-interactive environments: ```bash theme={null} codika login --api-key cko_your_api_key_here ``` Verify your identity: ```bash theme={null} codika whoami ``` Output: ``` Organization: My Company Key name: dev-key Key: cko_abc...xyz Scopes: deploy:use-case, workflows:trigger Expires: 2026-12-31 Profile: my-company ``` ## Step 3: Scaffold a use case ```bash theme={null} codika init my-first-automation --name "My First Automation" ``` This creates: ``` my-first-automation/ config.ts # Deployment configuration version.json # Version tracking (starts at 1.0.0) project.json # Platform project ID package.json # Dependencies (codika) tsconfig.json # TypeScript config for IDE support .gitignore # Ignores node_modules/ node_modules/ # Dependencies installed automatically workflows/ main-workflow.json # HTTP-triggered parent workflow scheduled-report.json # Schedule-triggered workflow text-processor.json # Sub-workflow (called by parent) skills/ main-workflow/SKILL.md # Agent skill for the HTTP workflow scheduled-report/SKILL.md # Agent skill for the scheduled workflow ``` The template includes three workflows demonstrating different trigger types (HTTP, schedule, sub-workflow), the mandatory Codika node pattern, and placeholder usage. It also includes two [agent skills](/concepts/agent-skills) that describe how AI agents can interact with the triggerable workflows. Dependencies are installed automatically so the use case is immediately deployable. ## Step 4: Validate ```bash theme={null} codika verify use-case ./my-first-automation ``` Expected output if valid: ``` ✓ Use case validation passed must: 0 should: 0 nit: 0 ``` If there are issues, the CLI lists each finding with rule ID, severity, file, and message. Use `--fix` to auto-fix what it can: ```bash theme={null} codika verify use-case ./my-first-automation --fix ``` ## Step 5: Deploy ```bash theme={null} codika deploy use-case ./my-first-automation ``` The CLI: 1. Reads `version.json` (1.0.0) 2. Bumps to 1.0.1 (patch by default) 3. Packages all workflow files and collects agent skills from `skills/` 4. Sends to the Codika platform API 5. On success: updates `version.json`, archives deployment locally, saves `devProcessInstanceId` to `project.json` Output: ``` ✓ Deployed successfully Version: 1.0.1 (API: 1.1) Workflows: 3 Project: abc123 Instance: def456 ``` ## Step 6: Trigger a workflow ```bash theme={null} codika trigger main-workflow --poll --payload-file - <<'EOF' {"message": "Hello world"} EOF ``` The `--poll` flag waits for execution to complete (default timeout: 120 seconds) and prints the result. ## Step 7: Check execution details If you need to debug: ```bash theme={null} codika get execution <executionId> --deep --slim ``` The `--deep` flag fetches sub-workflow executions recursively. The `--slim` flag strips noise for readability. ## Optional: Publish to production Once you're happy with your dev deployment, publish it to production: ```bash theme={null} codika publish <templateId> ``` The `templateId` is stored in `project.json` under the `deployments` map after each deploy. Check it with: ```bash theme={null} cat project.json | grep templateId ``` This creates a production process instance. See [publish](/operations/publish-use-case) for visibility and sharing options. ## Optional: Download skills for agents Your use case already includes agent skills (created during `init`). After deploying, agents can download them: ```bash theme={null} codika get skills ``` Or download directly into a Claude Code project: ```bash theme={null} codika get skills --output .claude/skills ``` Any compatible coding agent (Claude Code, Cursor, …) auto-discovers the skills and knows how to trigger your workflows. See [Agent Skills](/concepts/agent-skills) for the full story. ## What's next <CardGroup> <Card title="Agent plugin" icon="plug" href="/guides/claude-code-plugin"> Install the Codika plugin in Claude Code, Cursor, or any Open-Plugin host so agents can run these commands for you (`npx plugins add codika-io/plugin`). </Card> <Card title="Core concepts" icon="lightbulb" href="/concepts/use-cases"> Learn how use cases, processes, and workflows relate. </Card> <Card title="Build your own" icon="hammer" href="/guides/first-use-case"> Step-by-step guide to building a custom use case from scratch. </Card> <Card title="CLI Reference" icon="terminal" href="/operations/overview"> Complete reference for all CLI commands and options. </Card> <Card title="Validation rules" icon="check" href="/operations/verify-use-case"> Understand all validation rules enforced by the CLI. </Card> <Card title="Builder System" icon="wand-magic-sparkles" href="/builder/overview"> Let AI agents build use cases from your business requirements. </Card> </CardGroup> # Why Codika? Source: https://doc.codika.io/why-codika/overview Why an infrastructure layer between n8n and your business needs changes everything — for humans and AI agents alike ## The problem n8n is a powerful workflow automation engine. You can connect APIs, transform data, build complex logic, and automate almost anything. But there's a gap between "I built a workflow that works on my machine" and "I have a production-ready automation that multiple users can install, configure, and rely on." That gap includes: * **Credential management** — who owns which API keys? How do you isolate one user's Gmail tokens from another's? * **Multi-tenancy** — how do you let 50 organizations use the same automation without seeing each other's data? * **Versioning** — how do you roll out updates without breaking existing installations? * **Deployment** — how do you go from a workflow JSON file to a live, tested, monitored automation? * **Validation** — how do you catch errors before they hit production? * **Monitoring** — how do you track executions, diagnose failures, and know what's happening? These are all solvable problems. But solving them yourself means building infrastructure instead of building solutions. And in 2026, with AI agents capable of writing code, the bottleneck is no longer "can we write the code?" — it's "can we deploy, test, and iterate on software effectively?" That's the problem Codika solves. ## What Codika is Codika is an **infrastructure layer** that sits between n8n (the execution engine) and your business needs. ``` Your business needs (what to automate) → Codika (deploys, manages, isolates, versions, monitors) → n8n (executes the workflows) ``` We use n8n in the backend. We don't replace it — we orchestrate it. n8n is the engine that runs workflows. Codika is everything around that engine: the deployment pipeline, the credential vault, the version manager, the execution tracker, the multi-tenant isolation layer, and the agent toolkit. ### Use cases: workflow ensembles This is a fundamental difference from raw n8n. In n8n, you manage individual workflows. In Codika, you manage **use cases** — sets of workflows that work together as a single deployable unit. A use case packages: * Multiple n8n workflows (main workflows + sub-workflows) * A configuration file (`config.ts`) that defines triggers, integrations, schemas, and deployment parameters * Semantic versioning (`version.json`) * Agent skills (`SKILL.md` files) that describe what each endpoint does When you deploy a use case, Codika handles sub-workflow dependency ordering, placeholder replacement, credential injection, and metadata archival — all in a single command. The ensemble model means you think about **business processes**, not individual workflows. For example, an invoice processing use case might contain: * A Gmail trigger workflow that detects new invoices * A sub-workflow that extracts data from PDF attachments using Claude * A sub-workflow that validates extracted data against your CRM * An HTTP workflow that lets agents trigger manual processing These four workflows are deployed, versioned, and managed as one unit. Update one, redeploy the whole use case, and every installation gets the update. ## The three layers | Layer | Role | Example | | --------------------------- | -------------------- | ------------------------------------------------------------------------- | | **n8n** | Execution engine | Runs the workflow nodes, calls APIs, transforms data | | **Codika** | Infrastructure layer | Deploys workflows, manages credentials, tracks executions, isolates users | | **Your agents / your team** | Business layer | Describes what to automate, iterates on solutions, monitors results | n8n is pure infrastructure — it runs whatever you give it. Codika assembles the pieces and packages them into a service suited for production. Your team (or your agents) focuses on what matters: solving business problems. ## Agent-native by design Codika is built for a world where AI agents are primary users of automation infrastructure. Every design decision reflects this: **Agents call actions, not APIs.** Instead of giving an agent access to raw Twilio, Salesforce, or Google APIs, you build use cases that encapsulate specific business actions. An agent calls `codika trigger send-proposal` — not `POST https://api.twilio.com/...` with manually managed auth headers. **One key to revoke.** Each process instance has a single API key. Disable the instance and the agent loses access to every action in that use case. No credential rotation across 10 different services. **Agents never touch credentials.** Codika injects OAuth tokens, API keys, and secrets at runtime during workflow execution. Agents hold a Codika API key that grants access to predefined actions — nothing more. They never see, store, or transmit secrets for your integrations. **Skills make endpoints discoverable.** Agent skills are documentation files (`SKILL.md`) that describe what each endpoint does, what input it expects, and what output it returns. Agents download skills via `codika get skills` and immediately understand the available actions — no API exploration needed. **The Builder System.** Four autonomous agents that read the platform documentation, design workflow architectures, create all files, validate them, deploy to the platform, test them, and fix any issues — all from a natural language description of what you need. See [Builder System](/builder/overview) for details. ## Self-healing workflows When a workflow fails in raw n8n, you get an error log. You (or someone on your team) reads it, figures out what went wrong, edits the workflow, and redeploys. This is manual, slow, and requires n8n expertise. Codika changes this fundamentally. When a workflow fails, the platform has the full context: * **The business requirement** — the PRD or BRD that describes what this automation is supposed to achieve * **The architecture plan** — which workflows exist, how they connect, what each one does * **The configuration** — which integrations, which credential scopes, which deployment parameters * **The execution trace** — which node failed, what data it received, what error occurred With this context, Codika's agents can **diagnose and fix failures automatically**. A "credential not found" error? The agent knows whether to fix a placeholder suffix, add a missing integration to `config.ts`, or escalate to the user because an OAuth connection needs re-authorization. Raw n8n can detect a failure. But without knowing the overall goal of the software that was built, it can't make decisions about how to fix it. Codika can — because it knows what you're trying to achieve. ## What you get out of the box ### Credential isolation at scale Eleven credential scopes ensure every user, every organization, and every installation has exactly the access it needs: | Scope | What it isolates | Example | | ------------- | ---------------------------------------- | -------------------------------------------------------------------- | | **FLEXCRED** | AI providers with org-to-Codika fallback | Anthropic, OpenAI (org can override, falls back to Codika's default) | | **USERCRED** | Per-user OAuth tokens | Gmail, Google Sheets, Google Drive (each user connects their own) | | **ORGCRED** | Organization-wide shared credentials | Slack workspace, CRM API keys | | **INSTCRED** | Per-installation credentials | Each deployment can have its own Supabase instance | | **INSTPARM** | User-configured parameters | Company name, Slack channel, email filter criteria | | **SUBWKFL** | Sub-workflow references | Resolved to actual n8n IDs during deployment | | **SYSCREDS** | System-level credentials | Platform-managed, never exposed to users | | **MEMSECRT** | Member-level secrets | Execution authentication tokens | | **PROCDATA** | Process-level values | Namespace, process ID | | **USERDATA** | Per-user runtime values | Instance UID, user ID | | **ORGSECRET** | Organization secrets | Custom n8n URLs, internal API endpoints | All credentials are encrypted using hybrid RSA-OAEP + AES-GCM encryption. Private keys live in Google Cloud Secret Manager — never in code, never in config files. ### Deployment pipeline One command handles everything: ```bash theme={null} codika deploy use-case ./my-use-case --patch ``` Behind the scenes: 1. Validates the use case (30+ rules across 4 layers) 2. Base64-encodes all workflow JSON files 3. Bumps the semantic version 4. Sends everything to the Codika platform API 5. Platform creates versioned deployment records 6. Deploys workflows to n8n with all placeholders replaced 7. Orders sub-workflows before parent workflows (dependency resolution) 8. Archives the deployment locally for rollback 9. Updates `project.json` with instance IDs ### Validation before deployment Thirty-plus rules organized in four layers catch issues before they reach production: | Layer | What it checks | | ---------------------------- | ------------------------------------------------------------------------------------------------ | | **Flowlint graph analysis** | Workflow structure, mandatory Codika nodes (Init, Submit Result, Report Error) | | **Codika pattern rules** | Sub-workflow parameters, webhook path convergence | | **Workflow content scripts** | Placeholder syntax, credential patterns, retry configuration, LLM model IDs | | **Use-case folder scripts** | Config exports, workflow imports, sub-workflow references, integration consistency, schema types | Auto-fix is available for 8+ common issues: `codika verify use-case ./my-use-case --fix`. ### Dev/Prod environments Every process instance supports separate dev and prod environments. Test in dev, promote to prod with `codika publish`. Each environment has its own credentials, execution tracking, and API keys. ### Execution tracking Structured execution records with: * Per-execution UUID tracking (time-sortable UUIDs) * Error classification: node failure, timeout, validation error, external API error * Failed node identification and last successful node tracking * Per-org error workflows that capture all failures * LLM cost calculation (token usage per execution) * Deep inspection: `codika get execution --deep --slim` traverses sub-workflow calls recursively ### Credit-based billing Built-in monetization with four plan types: | Plan | Credits/month | Seats | | ---------- | ------------- | ----- | | Free | 200 | 2 | | Pro | 10,000 | 5 | | Business | 50,000 | 10 | | Enterprise | 200,000+ | 50+ | Credits are consumed per workflow execution. No custom billing infrastructure needed. ### RAG and knowledge base Per-process-instance knowledge base with: * Document upload and vector embedding (Pinecone integration) * Semantic versioning for knowledge documents * Automatic enrichment: execution results stored as knowledge documents * File parsing for PDF, DOCX, TXT, and more ### Publishing and marketplace Deploy a use case, then publish it for others: * **Private** — only the owner can see it * **Organization** — all org members can install it * **Marketplace** — public discovery and installation Each installation gets its own isolated credentials, parameters, and execution tracking. ### AI-driven project stages Structured requirements-to-documentation pipeline: 1. **Discovery/Requirements** — user describes the business need 2. **Solution Architecture** — AI generates the technical design 3. **Implementation Plan** — AI generates the build plan 4. **User Manual** — AI generates documentation Each stage builds on the previous ones. Edit any stage and downstream stages are regenerated. ## The bottom line Winning with AI agents does not require technical skills — it requires the ability to deploy and iterate on software effectively. Codika provides the infrastructure for that iteration loop: from natural language requirements to production-ready automations, with credential isolation, version management, execution tracking, and self-healing built in. n8n is a powerful engine. Codika makes it production-ready. ## Next steps <CardGroup> <Card title="Codika vs Alternatives" icon="scale-balanced" href="/why-codika/vs-n8n"> How Codika compares to no-code tools and what it adds on top of n8n. </Card> <Card title="Codika and AI Agents" icon="robot" href="/why-codika/with-agents"> How Codika works with Claude Code and other AI agents. </Card> <Card title="Quickstart" icon="rocket" href="/quickstart"> Install the CLI and deploy your first use case in minutes. </Card> <Card title="Builder System" icon="wand-magic-sparkles" href="/builder/overview"> Let AI agents create use cases from your business requirements. </Card> </CardGroup> # Codika vs Alternatives Source: https://doc.codika.io/why-codika/vs-n8n How Codika compares to no-code tools like Zapier and Make, and what it adds on top of raw n8n — the execution engine it uses under the hood ## Why not Zapier, Make, or other no-code tools? No-code workflow tools were built to solve a real problem: business users couldn't write code, so these platforms created visual interfaces to let them build automations by dragging and dropping blocks. That made sense in a world where code was expensive and hard to produce. That world is over. ### The premise of no-code is obsolete No-code tools exist because humans struggle with code. They simplify workflows into visual canvases, abstract away API calls, and hide the complexity behind friendly UIs. Every design decision optimizes for **human readability and human interaction**. But AI agents don't struggle with code. They write it faster than any human, they don't make typos, and they don't need visual canvases to understand what a workflow does. An agent reading a JSON workflow file understands it instantly — the visual editor adds nothing. When agents are better coders than the best developers in the world, **simplifying code for humans is solving the wrong problem**. The future is a world where agents execute and humans orchestrate. Humans define what they want. Agents build it, deploy it, test it, fix it. The role of infrastructure is not to simplify things for humans — it's to give agents the guardrails, tooling, and deployment pipeline they need to iterate fast and reliably. ### What no-code tools get wrong for an agent-first world | No-code assumption | Why it breaks with agents | | -------------------------------------------- | ------------------------------------------------------------------------------------------- | | **Visual editors help users build** | Agents don't use visual editors — they generate JSON, code, and API calls directly | | **Simplify integrations into drag-and-drop** | Agents can write any API call natively — simplification adds constraint without benefit | | **Pre-built connectors for common tools** | Agents can use any API with any authentication — they don't need pre-built wrappers | | **Human-readable execution logs** | Agents need structured, machine-readable execution data — not screenshots of colored blocks | | **Manual trigger and test buttons** | Agents need scriptable CLI commands: `codika trigger --poll`, not a "Run" button | | **Per-user pricing based on "tasks"** | Agents execute thousands of operations — task-based pricing becomes prohibitively expensive | | **Walled garden of supported integrations** | Agents can call any HTTP endpoint — they're not limited to a catalog | ### What Codika gets right Codika doesn't simplify code. It provides **infrastructure for code**: * **Full n8n workflow JSON** — no abstraction layer, no visual-only editing. Agents read and write workflows directly. * **Programmatic CLI** — every operation is a scriptable command. Deploy, trigger, debug, manage integrations — all from the terminal or an agent's tool loop. * **30+ validation rules** — instead of hoping a visual editor prevents mistakes, Codika runs structural and semantic checks before deployment. * **Agent skills** — machine-readable documentation that describes what each endpoint does, what input it expects, what output it returns. No visual UI needed. * **The Builder System** — four autonomous agents that create, modify, test, and fix use cases. This isn't possible on platforms designed for human visual interaction. * **Self-healing** — when workflows fail, agents diagnose and fix them using business context. This requires programmatic access to execution traces, not a visual debugger. No-code tools made automation accessible to humans who couldn't code. Codika makes automation infrastructure accessible to agents who can code better than anyone — and to the humans who orchestrate them. ### The real comparison | | Zapier / Make | Codika | | ---------------------- | -------------------------------------- | ---------------------------------------------------------------- | | **Designed for** | Humans who can't code | Agents who code better than humans + humans who orchestrate them | | **Workflow format** | Visual canvas (proprietary) | n8n workflow JSON (open, readable, writable) | | **Building interface** | Drag-and-drop editor | CLI + agents that generate code | | **Integration model** | Pre-built connectors (walled garden) | Any API via n8n nodes + custom integrations | | **Testing** | Manual "Run" button | `codika trigger --poll` (scriptable, automatable) | | **Debugging** | Visual execution viewer | `codika get execution --deep --slim` (structured, traversable) | | **Multi-tenancy** | Per-account isolation only | Org → Project → Instance hierarchy with 11 credential scopes | | **Versioning** | Limited or none | Semantic versioning with deployment history | | **Agent integration** | API access (generic) | Agent skills, Builder System, self-healing | | **Self-healing** | None | Agents fix failures using business context (PRD/BRD) | | **Pricing model** | Per-task (expensive at scale) | Credit-based (designed for high-volume agent usage) | | **Iteration speed** | Human-limited (click, configure, test) | Agent-speed (describe → build → deploy → test → fix → repeat) | *** ## We use n8n — we don't replace it Codika deploys workflows **to** n8n. n8n executes them. We handle everything around that: deployment, credential management, multi-tenancy, versioning, validation, monitoring, and agent integration. Think of it like Kubernetes and Docker. Docker runs containers. Kubernetes orchestrates them at scale — scheduling, networking, scaling, health checks, rolling updates. You wouldn't run Docker in production without an orchestration layer. The same principle applies here: you wouldn't run n8n workflows in production for multiple users without an infrastructure layer. n8n is the execution engine. Codika is the production infrastructure. ## The full comparison | Capability | Raw n8n | Codika + n8n | | ------------------------------- | ------------------------------- | ---------------------------------------------------------------------------------- | | **Workflow execution** | Direct | Via n8n (unchanged) | | **Use case packaging** | Individual workflow files | `config.ts` + `workflows/` as a deployable unit — multiple workflows work together | | **Multi-workflow coordination** | Manual sub-workflow management | Built-in: use cases are ensembles with automatic dependency ordering | | **Multi-tenancy** | Single tenant (DIY RBAC) | Org → Project → Instance hierarchy with per-user isolation | | **Credential isolation** | Shared credentials per instance | 11 scopes (FLEXCRED, USERCRED, ORGCRED, INSTCRED, etc.) | | **OAuth management** | Per-instance, manual setup | Auto-sync from Codika dashboard to n8n, 30+ integration handlers | | **Secret encryption** | n8n's built-in encryption | Hybrid RSA-OAEP + AES-GCM, private keys in Secret Manager | | **Deployment** | Export JSON, POST to n8n API | `codika deploy` — validates, encodes, versions, deploys, archives | | **Version management** | None | Semantic versioning (major.minor.patch) with deployment history | | **Dev/Prod environments** | Separate n8n instances | Built-in toggle per process instance, same n8n backend | | **Pre-deployment validation** | None (runtime errors) | 30+ rules across 4 layers, auto-fix for 8+ issues | | **Execution tracking** | n8n execution logs | Structured errors, UUID tracking, per-org error workflows, LLM cost calc | | **Agent integration** | MCP server (raw access) | Agent skills, API keys, trigger patterns, Builder System | | **Self-healing** | None | Agents diagnose and fix failures using PRD/BRD business context | | **Billing** | DIY | Credit-based with 4 plan types (Free → Enterprise) | | **Publishing / Marketplace** | None | Share automations across organizations with isolation | | **Data ingestion (RAG)** | Manual implementation | Built-in Pinecone integration, per-instance knowledge base | | **Scaffolding** | Empty workflow editor | `codika init` generates templates with mandatory patterns | | **Project stages** | None | AI-driven pipeline: requirements → architecture → implementation → docs | ## Deep dive: use cases as workflow ensembles In raw n8n, you manage individual workflows. Each workflow is independent — it has its own trigger, its own credentials, its own configuration. If you have a business process that spans multiple workflows, you manually keep them in sync. In Codika, the deployment unit is the **use case** — a set of workflows that work together. ``` my-use-case/ ├── config.ts # Orchestration: triggers, integrations, schemas, parameters ├── version.json # Semantic version ├── workflows/ │ ├── main-workflow.json # Gmail trigger → extract data → validate │ ├── extract-data.json # Sub-workflow: PDF parsing with Claude │ └── validate-crm.json # Sub-workflow: CRM lookup and validation └── skills/ └── process-invoice/ └── SKILL.md # Agent-readable endpoint documentation ``` The `config.ts` file defines the orchestration: * Which workflows belong to this use case * Which triggers activate which workflows (HTTP, schedule, service event) * Which integrations are required (and which credential scope each uses) * What input/output schemas look like * What parameters users configure at installation time When you deploy, Codika: 1. Resolves sub-workflow dependencies (deploys `extract-data` and `validate-crm` before `main-workflow`) 2. Replaces all placeholders with real values per user (credentials, parameters, workflow IDs) 3. Creates versioned deployment records 4. Archives the configuration for audit and rollback This ensemble model is what makes agent-driven development possible. Agents think in terms of "what does this business process need?" not "what should this one workflow do?" ## Deep dive: credential isolation Raw n8n runs a single credential store. Everyone sharing the instance sees every credential. There's no concept of "this Gmail connection belongs to User A" or "this Slack token belongs to Organization B." Codika introduces **11 different credential scopes**, each with specific isolation guarantees: ### AI providers: FLEXCRED ``` {{FLEXCRED_ANTHROPIC_ID_DERCXELF}} ``` AI provider credentials with automatic fallback. If the organization has configured their own Anthropic API key, it's used. If not, Codika's default key is used. This means: * New users can start building AI workflows immediately (using Codika's key) * Organizations can bring their own keys for cost control and rate limit management * The switch is transparent — no workflow changes needed ### Per-user OAuth: USERCRED ``` {{USERCRED_GMAIL_ID_DERCRESU}} ``` Each user connects their own OAuth integrations (Gmail, Google Sheets, Google Drive, Microsoft Teams, Outlook). When a workflow runs for User A, it uses User A's Gmail token. User B's token is completely separate. Codika auto-syncs OAuth tokens from the dashboard to n8n credentials. When a user connects Gmail, the platform: 1. Completes the OAuth flow 2. Stores the token in Firestore (encrypted) 3. Creates a corresponding n8n credential 4. Maps the placeholder to the n8n credential ID Disconnecting removes everything — Firestore record, n8n credential, placeholder mapping. ### Organization-wide: ORGCRED ``` {{ORGCRED_SLACK_ID_DERCGRO}} ``` Shared across all members of an organization. Typical for tools everyone uses: Slack workspace, CRM, project management. One admin connects it, everyone benefits. ### Per-installation: INSTCRED ``` {{INSTCRED_SUPABASE_ID_DERCTSNI}} ``` Each installation of a use case can have different credentials. Deploy the same use case to two organizations — one points to their Supabase instance, the other to theirs. The workflow is identical; the credentials are isolated. ### Deployment parameters: INSTPARM ``` {{INSTPARM_COMPANY_NAME_MRAPTSNI}} ``` User-provided values configured at installation time. Not credentials, but configuration: company name, Slack channel, email filter criteria, report frequency. Validated against a JSON schema defined in `config.ts`. ### Placeholder replacement timing All placeholders are replaced **at deployment time**, not runtime. This means: * Faster workflow execution (no lookup delays) * No credential leakage in execution logs * Deterministic behavior — what you deployed is what runs Credential naming uses SHA-256 hashes to ensure uniqueness and avoid collisions across users and organizations. ## Deep dive: validation before deployment In raw n8n, you discover errors when workflows fail in production. A misconfigured credential, a missing node connection, a wrong placeholder suffix — you find out at runtime. Codika runs **30+ validation rules** before any HTTP request is made. Four layers, catching progressively deeper issues: ### Layer 1: Flowlint graph analysis Structural validation of the workflow graph: * Every parent workflow must have a **Codika Init** node after the trigger * Every terminal path must end with **Submit Result** (success) or **Report Error** (failure) * Sub-workflows must not have Codika Init/Submit/Report nodes * Sub-workflows must declare at least one input parameter ### Layer 2: Codika pattern rules Platform-specific patterns: * HTTP and schedule triggers must have matching webhook paths * Sub-workflow minimum parameter requirements ### Layer 3: Workflow content scripts (13 checks) Content-level validation: * **Placeholder syntax** — all 11 types must use correct reversed suffixes (FLEXCRED → \_DERCXELF) * **Credential placeholders** — no hardcoded values * **Retry configuration** — API/HTTP nodes should have retry with backoff * **Instance parameter quoting** — correct string formatting * **LLM model IDs** — valid Claude/GPT model references * **Webhook IDs** — correct format * **Node connections** — no orphaned nodes, all IF branches connected * **AI credentials** — on the model node, not on chainLlm/agent * **Sub-workflow wait** — calls must use "Wait for completion" * **Database nodes** — must have "Always output data" enabled ### Layer 4: Use-case folder scripts (12 checks) Folder-level consistency: * **Config exports** — `WORKFLOW_FILES` and `getConfiguration()` must exist * **Workflow imports** — all workflows in config must match actual files * **Sub-workflow references** — `SUBWKFL` placeholders must reference existing template IDs * **Integration inheritance** — workflows must declare all integrations they use (including sub-workflow dependencies) * **Trigger consistency** — types must be valid and consistent * **Schema validation** — input/output schemas must use valid field types * **Skill consistency** — skill files must match declared workflows * **Custom integration schemas** — `cstm_*` integrations must have valid schemas ### Auto-fix Eight-plus common issues are automatically fixable: ```bash theme={null} codika verify use-case ./my-use-case --fix ``` Fixes include: placeholder syntax correction, retry configuration, JSON formatting, instance parameter quoting, integration inheritance propagation. For CI/CD pipelines: `codika verify use-case ./my-use-case --strict` treats warnings as errors. ## Deep dive: deployment pipeline Raw n8n deployment: export a JSON file, POST it to the n8n API, manually map credentials, hope it works. Codika deployment with `codika deploy use-case ./my-use-case --patch`: ``` 1. Read config.ts → validate exports 2. Load all workflow JSON files → base64 encode 3. Collect metadata documents (README, PRD) 4. Discover and read agent skill files 5. Run all 30+ validation rules 6. Bump semantic version (patch: 1.0.0 → 1.0.1) 7. POST to Codika platform API 8. Platform creates: - Process definition (published entity) - Deployment configuration snapshot - Process instance (per-user installation) 9. Platform deploys to n8n: - Resolve sub-workflow dependencies (deploy children first) - Replace all placeholders with real values per user - Create/update workflows in n8n - Activate workflows 10. Archive deployment locally: - deployment-info.json (metadata, n8n IDs) - config-snapshot.json (full configuration) - workflows/*.json (copies of deployed files) 11. Update project.json (instance IDs, version) ``` Every deployment is archived. Rollback means redeploying a previous version — the local archive has everything needed. ## Deep dive: execution tracking Raw n8n gives you execution logs in the n8n UI. Codika adds structured tracking: **Per-execution records:** * Time-sortable UUID v7 identifiers * Execution status: pending → running → success/failed * Structured error details: error type, failed node, last successful node, HTTP status, stack trace * Error classification: `node_failure`, `timeout`, `validation_error`, `external_api_error`, `unknown` **Execution metadata injected into workflows:** * Execution ID + secret (for result validation) * Callback URL (workflows report results back to the platform) * Full context: workflowId, processId, processInstanceId, userId, organizationId **Per-org error workflows:** * Every organization gets a dedicated error workflow in n8n * All execution failures are routed to this workflow * Enables org-specific error handling, alerting, and escalation **CLI debugging:** ```bash theme={null} # List recent executions codika list executions <instanceId> --failed-only --limit 10 # Deep inspection with sub-workflow traversal codika get execution <executionId> --deep --slim ``` The `--deep` flag recursively fetches sub-workflow executions, giving you the full execution tree. The `--slim` flag strips noise for readability. No need to log into the n8n UI. ## The analogy | Raw n8n | Codika + n8n | | ----------------- | ------------------------------------------------ | | Docker | Kubernetes | | A web server | A hosting platform | | A database engine | A managed database service | | Writing assembly | Writing in a high-level language with a compiler | The pattern is the same: take a powerful low-level tool and add the infrastructure that makes it production-ready at scale. n8n runs workflows. Codika makes them deployable, manageable, and maintainable. ## When to use raw n8n vs Codika **Raw n8n is great when:** * You're the only user and you manage your own instance * You're prototyping a single workflow * You want full control over the n8n instance * You don't need multi-tenancy, versioning, or agent integration **Codika adds value when:** * Multiple users or organizations need the same automation with isolated credentials * You want agents to build, deploy, and maintain workflows * You need version management, dev/prod environments, and deployment history * You want pre-deployment validation (30+ rules) instead of runtime errors * You need structured execution tracking and error diagnosis * You want to publish and share automations across organizations * You want self-healing: agents that fix failed workflows using business context * You need billing, credit tracking, and usage analytics They're not competing tools. n8n is the engine. Codika is the infrastructure that makes it production-ready. # Codika and AI Agents Source: https://doc.codika.io/why-codika/with-agents How Codika works with coding agents (Claude Code, Cursor, …) — not either/or, but better together ## The question people ask "Why use Codika when my coding agent can already write n8n workflows?" The answer is simple: **you use both**. The agent writes the code. Codika provides the infrastructure to deploy, test, maintain, and iterate on it. The real question is: "What tool do you give your agent to make it effective at building and managing automations?" Without Codika, a coding agent (Claude Code, Cursor, …) can create n8n workflow JSON files and use the n8n MCP server to deploy them. But it has no deployment pipeline, no validation rules, no credential management, no version control, no multi-tenancy, no execution debugging, and no way to fix failures based on business context. With Codika, the agent gets a complete toolkit — installable in one command (`npx plugins add codika-io/plugin`): | Capability | What the agent uses | | ---------------------- | -------------------------------------------------------------------- | | Scaffolding | `codika init` — generates templates with mandatory patterns | | Validation | `codika verify` — 30+ rules with auto-fix before deployment | | Deployment | `codika deploy` — one command, handles everything | | Testing | `codika trigger --poll` — fire a workflow, wait for results | | Debugging | `codika get execution --deep --slim` — full execution trace | | Integration management | `codika integration set/list/delete` — encrypted credential handling | | Status checking | `codika status` — is this use case ready to deploy? | | Skill discovery | `codika get skills` — understand what endpoints are available | This isn't "Codika or your coding agent." It's "your coding agent + the Codika tool." ## The agent development loop Building automations with agents follows a natural loop: ``` 1. Describe what you need → "I need daily reports from Supabase sent to Slack" 2. Agent designs the architecture → reads Codika docs, picks triggers, integrations, workflows 3. Agent creates all files → config.ts + workflow JSON files 4. Agent validates → codika verify use-case (catches issues early) 5. Agent deploys → codika deploy use-case (one command) 6. Agent tests → codika trigger + codika get execution 7. Agent fixes issues → edit workflow → verify → deploy again 8. Repeat until it works ``` The [Builder System](/builder/overview) automates this entire loop with four specialized agents. The `use-case-builder` designs the architecture, `n8n-workflow-builder` creates each workflow, `use-case-tester` deploys and tests, and `use-case-modifier` handles fixes and enhancements. Each step in this loop depends on Codika's infrastructure. Without it, agents would need to: * Manually manage n8n API calls for deployment * Handle credential injection themselves * Parse raw n8n execution logs for debugging * Track versions in custom metadata files * Build their own validation logic Codika's CLI skills abstract all of this. The agent focuses on **what** to build, not **how** to deploy it. ## Treat agents like new employees, not sysadmins When you hire a new employee, you don't hand them the root password to every system on day one. You tell them what to do: > "Find this user in our database. Check in HubSpot whether they're a client. If yes, pull their latest invoice. Check if it's paid. If not, send them a reminder email." That task spans **five different systems** — a database, a CRM, an invoicing platform, a payment gateway, and an email provider. But the employee doesn't need admin access to any of them. They need a clear action to perform, with appropriate access to the specific data they need. Now look at how most teams set up AI agents today. They give the agent: * Full Supabase access (every table, every row) * Full HubSpot API key (every contact, every deal) * Full invoicing system access (every invoice, every payment) * Full email sending capability (to anyone, about anything) This is the equivalent of giving a new hire the root password on day one. It's a **security risk**, an **operational risk**, and a **scope risk** — the agent can do far more than it should. ### The Codika approach: custom action APIs Codika inverts this model. Instead of giving agents access to your tools, you build **highly custom APIs on top of your existing tools**. Each API represents one specific action: | Action API | What it does behind the scenes | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | | `check-invoice-status` | Queries Supabase for the user → looks up HubSpot client record → fetches invoice → checks payment status → returns structured result | | `send-payment-reminder` | Takes a user ID → fetches their email and invoice details → generates a personalized reminder → sends via your email provider | | `update-crm-record` | Takes a contact ID and fields → validates the data → updates HubSpot → logs the change | Each of these is a Codika use case — a workflow ensemble that encapsulates multi-step business logic across multiple integrations. The agent triggers them via a single HTTP endpoint with a simple JSON payload. **What the agent sees:** ```json theme={null} { "action": "check-invoice-status", "input": { "userId": "usr_12345" } } ``` **What the agent never sees:** * Supabase connection string * HubSpot API key * Invoice system credentials * Email provider SMTP settings The agent knows "check-invoice-status" and "send-payment-reminder" — exactly the actions you defined, nothing more. This is the principle of **least privilege** applied to AI agents. ### Why this matters at scale As you add more agents and more capabilities, the custom action API model scales cleanly: * **Adding a new action** means building a new use case and publishing it. Existing agents don't change. * **Revoking access** means disabling the process instance. One API key gone, all actions removed. * **Auditing** means checking execution logs — every action is tracked with structured metadata. * **Updating logic** means deploying a new version of the use case. All agents get the update automatically. Compare this to the alternative: managing API keys for 10 services across 5 agents, each with different permissions, different rotation schedules, and different audit trails. It doesn't scale. This is the future we're building: a world where agents interact with **purpose-built action APIs**, not raw infrastructure. Codika is the platform that makes building those APIs fast, safe, and maintainable. ## Agents need guardrails, not freedom A raw n8n API gives agents unlimited freedom. They can create any workflow, any credential, any configuration. But freedom without structure leads to inconsistent, hard-to-debug, unmaintainable workflows. Codika provides guardrails that keep agent output consistent and production-ready: **Mandatory workflow patterns.** Every parent workflow must follow: Trigger → Codika Init → Business Logic → IF (success?) → Submit Result / Report Error. This isn't a suggestion — the validation system enforces it. Agents can't deploy a workflow that doesn't follow the pattern. **Placeholder system.** Credentials, parameters, and references use typed placeholders with validated syntax. Agents can't hardcode API keys or connection strings — the validation system catches it. **30+ validation rules.** Before any deployment, the use case is checked for structural integrity, credential patterns, placeholder syntax, schema consistency, and more. Issues are caught before they reach production. **Documentation-driven building.** The Builder System agents read the same platform documentation humans would. They understand **why** patterns exist (credential isolation, execution tracking, error handling), not just **what** to create. This produces workflows that follow conventions naturally, not through blind compliance. The result: agent-created workflows are indistinguishable from human-created ones. They follow the same patterns, use the same conventions, and pass the same validation rules. ## Agents need context to self-heal When a workflow fails in raw n8n, you get an error log: ``` ERROR: NodeOperationError: The credential "Gmail OAuth2" does not exist ``` This tells you what happened, but not **why** or **how to fix it**. Is the credential name wrong? Was it deleted? Does the user need to re-authorize? Is the placeholder suffix incorrect? The error log doesn't say. When the same failure happens in Codika, the platform has the full context: * **The business requirement** — the PRD that says "monitor Gmail for new client emails" * **The configuration** — `config.ts` declares Gmail as a USERCRED integration * **The placeholder** — `{{USERCRED_GMAIL_ID_DERCRESU}}` in the workflow * **The execution trace** — Codika Init succeeded, Gmail trigger node failed * **The integration state** — user connected Gmail on March 15, token last refreshed March 20 With this context, Codika's agents can diagnose systematically: 1. Is the placeholder suffix correct? (DERCRESU = USERCRED reversed — yes, correct) 2. Is the integration declared in `config.ts`? (Yes — `gmail` with scope `usercred`) 3. Is the user's OAuth connection active? (Check platform — token expired) 4. Resolution: escalate to user — "Your Gmail connection needs re-authorization" Or for a different error: 1. "Credential not found" on a FLEXCRED\_ANTHROPIC placeholder 2. Check suffix — DERCXELF = FLEXCRED reversed — correct 3. Check `config.ts` — integration declared as `anthropic` with scope `flexcred` 4. Check organization integration — not configured 5. Check Codika fallback — fallback key exists 6. Resolution: the org integration ID is mismatched — fix the `integrationUid` in `config.ts`, deploy again with `codika deploy use-case` This diagnostic capability is only possible because Codika maintains the full context of what you're building. Raw n8n has none of this context — it just runs workflows. ## Agents need security boundaries Giving agents direct access to OAuth tokens, API keys, and database credentials is a security and operational nightmare: * **Token theft** — a compromised agent leaks credentials to every service it has access to * **Scope creep** — an agent with full API access can perform actions beyond its intended purpose * **Rotation complexity** — rotating one credential means updating every agent that uses it * **Audit difficulty** — who accessed what, when, and through which agent? Codika provides clean security boundaries: **Single API key.** Each process instance has one Codika API key (`ck_` prefix). This key grants access to the actions defined in that use case — nothing more. The agent never holds OAuth tokens, API keys, or database credentials for any integration. **Runtime credential injection.** When a workflow executes, Codika injects the correct credentials at runtime. Placeholders in the workflow are replaced with real values during deployment. The agent's trigger request contains only the business payload — no auth headers, no tokens. **Instant revocation.** Disable the process instance and the agent loses access to every action immediately. No credential rotation across 10 services. No wondering "did we remove access everywhere?" **Structured audit trail.** Every execution is tracked with: who triggered it (API key), when, what workflow, what input, what result, what errors. Per-org error workflows capture all failures. ## Agents need a stable API surface Raw n8n workflows change constantly — new versions, renamed nodes, updated schemas, different output formats. An agent that worked yesterday might break today because a node was renamed. Codika's agent skills provide a **stable, documented API surface**: ```markdown theme={null} --- name: check-invoice-status description: Check the payment status of a user's latest invoice workflowTemplateId: check-invoice --- ## Endpoint POST /trigger/{processInstanceId}/{workflowId} ## Input | Field | Type | Required | Description | |-------|------|----------|-------------| | userId | string | yes | The user ID to check | ## Output | Field | Type | Description | |-------|------|-------------| | status | string | "paid", "overdue", or "pending" | | amount | number | Invoice amount | | dueDate | string | ISO 8601 date | ``` Agents download skills via `codika get skills` and have a complete, up-to-date understanding of available actions. The skills format follows the open [Agent Skills specification](https://agentskills.io/specification), making them natively compatible with any compliant agent host (Claude Code, Cursor, …). The deployment pipeline ensures skills stay in sync with workflows. When you deploy a new version of a use case, the skills are repackaged with the deployment. An agent that re-downloads skills always gets the current version. ## The infrastructure agents need | What agents need | Without Codika | With Codika | | -------------------------- | ------------------------------- | ------------------------------------ | | Deploy workflows | Manual n8n API calls | `codika deploy` (one command) | | Validate before deploying | Hope it works | 30+ validation rules with auto-fix | | Test a workflow | Manually call n8n webhook | `codika trigger --poll` (scriptable) | | Debug a failure | Parse raw n8n execution logs | `codika get execution --deep --slim` | | Manage credentials | Handle OAuth tokens directly | Placeholders resolved at deploy time | | Version and rollback | Manual file management | Semantic versioning built-in | | Discover available actions | Read n8n API docs | Agent skills (SKILL.md) | | Iterate and fix | Start from scratch | Edit → verify → deploy cycle | | Fix failures automatically | Can't (no business context) | Self-healing with PRD/BRD context | | Limit agent scope | Give raw API keys (full access) | Custom action APIs (least privilege) | ## The Builder System Codika includes a [Builder System](/builder/overview) — four specialized agents that automate the entire use case lifecycle: | Agent | Role | | ------------------------ | ------------------------------------------------------------------- | | **use-case-builder** | Architect — designs and creates new use cases from natural language | | **use-case-modifier** | Surgeon — modifies existing use cases with targeted changes | | **n8n-workflow-builder** | Craftsperson — builds individual workflow JSON files | | **use-case-tester** | QA — deploy-trigger-inspect-fix loops (max 5 iterations) | These agents read the same platform documentation you would, design architectures based on your business requirements, create all the files, validate them, deploy to the platform, test them, and iteratively fix any issues. The Builder System is the proof of concept for agent-native infrastructure. When the platform is designed for agents from the ground up, agents can do things that would be impossible on raw infrastructure: * **Design from intent** — describe a business goal, get a complete architecture * **Build with conventions** — every workflow follows platform patterns because the agent read the documentation * **Test systematically** — automated deploy-test-fix loops with structured execution inspection * **Self-heal** — diagnose and fix failures using business context, not just error logs This is what it looks like when infrastructure is built for the agents that use it.