# 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 ` | Markdown content |
| `--file ` | Read content from a file instead of `--content` |
Content can also be piped via stdin: `echo "..." | codika notes upsert --type --summary "..."`
\| `--agent-id ` | Agent identifier for tracking |
\| `--major-change` | Bump minor version instead of patch |
\| `--api-key ` | API key override |
\| `--json` | JSON output |
### Get options
| Flag | Description |
| ---------------------------- | ------------------------------------- |
| `--type ` | **(Required)** Document type ID |
| `--target-version ` | Get a specific version (e.g. `0.1.0`) |
| `--history` | Show all versions |
| `--api-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 ` |
| "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 ` | 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 ` | Deploy workflows to the platform with version management |
| [Deploy Data Ingestion](/operations/deploy-data-ingestion) | `deploy process-data-ingestion ` | Deploy RAG/embedding pipeline configuration |
| [Deploy Documents](/operations/deploy-documents) | `deploy documents ` | Upload stage documentation to the platform |
| [Publish Use Case](/operations/publish-use-case) | `publish ` | 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 ` | Execute a deployed workflow via HTTP |
| [Fetch Use Case](/operations/fetch-use-case) | `get use-case ` | Download a deployed use case from the platform |
| [Get Execution](/operations/get-execution) | `get execution ` | 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 ` | 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 ` | 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 ` | Override API key |
| `--api-url ` | Override API base URL |
| `--project-file ` | Path to custom project file (default: `project.json`) |
| `--profile ` | 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 # Scaffold a new use case
├── config
│ ├── set # Save API key and base URL
│ ├── show # Display all profiles
│ └── clear # Remove configuration
├── verify
│ ├── use-case # Validate entire use case folder
│ └── workflow # Validate single workflow file
├── deploy
│ ├── use-case # Deploy use case to platform
│ ├── process-data-ingestion # Deploy data ingestion config
│ └── documents # Upload stage documentation
├── publish # Publish deployment to production
├── rerun deployment # Rerun deployment with updated parameters
├── integration
│ ├── set # Create or update an integration
│ ├── list # List integrations and connection status
│ └── delete # Delete an integration
├── trigger # Trigger a deployed workflow
├── get
│ ├── use-case # Fetch deployed use case
│ ├── execution # Fetch execution details
│ ├── instance [instanceId] # Inspect live instance details
│ ├── project # Inspect project details
│ └── skills [instanceId] # Fetch agent skill documents
├── instance
│ ├── activate [instanceId] # Activate a process instance
│ └── deactivate [instanceId] # Deactivate a process instance
├── list
│ ├── executions # 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 [options]
```
## Arguments
| Argument | Description |
| -------------- | ------------------------------------------------------------ |
| `` | Deployment template ID (from `project.json` deployments map) |
## Options
| Option | Description | Default |
| ------------------------ | ------------------------------------------------------------- | ----------------------------- |
| `--path ` | Path to use case folder with project.json | Current directory |
| `--project-file ` | Custom project file path | `project.json` |
| `--project-id