# Agentled — Complete CLI & API Reference for LLMs

> This file contains everything an AI agent needs to use Agentled.
> It is designed to be consumed in a single read by LLMs like Claude, GPT, Gemini, etc.

---

## 1. Authentication

```bash
# Option A: Environment variable
export AGENTLED_API_KEY=wsk_your_key_here
export AGENTLED_URL=https://www.agentled.app  # optional, defaults to this
export AGENTLED_WORKSPACE=inovexus            # optional saved workspace selector

# Option B: CLI login (stores one or more workspace profiles in ~/.agentled/config.json)
agentled auth login

# Direct API key login
agentled auth login --key wsk_your_key_here

# Check status
agentled auth status
agentled auth current

# List / switch / remove saved workspaces
agentled auth list
agentled auth use bestseo4u
agentled auth remove bestseo4u

# Override the active workspace for one command
agentled --workspace inovexus workflows list

# Logout
agentled auth logout
```

Generate an API key in Agentled UI: Workspace Settings > Developer.

The CLI keeps multiple saved workspace profiles and uses the active profile by default.
Use `agentled auth list` and `agentled auth use <workspace>` to switch targets.
For scripts and one-off commands, prefer `agentled --workspace <workspace> ...`
or `AGENTLED_WORKSPACE=<workspace> ...`.

---

## 2. CLI Commands

All commands output JSON by default (optimized for machine parsing).
Add `--format table` for human-readable output, `--format minimal` for piping.

### Workflows

```bash
# List workflows
agentled workflows list
agentled workflows list --status live --limit 10

# Get workflow details (full pipeline, steps, metadata)
agentled workflows get <workflow-id>

# Create workflow from JSON file
agentled workflows create --file pipeline.json

# Create workflow from inline JSON
agentled workflows create --pipeline '{"name":"My Workflow","steps":[...]}'

# Update workflow (partial update)
agentled workflows update <id> --updates '{"name":"New Name"}'
agentled workflows update <id> --file updates.json

# Delete workflow (permanent)
agentled workflows delete <id>

# Validate pipeline structure (returns errors per step)
agentled workflows validate <id>

# Publish / pause / archive
agentled workflows publish <id> --status live
agentled workflows publish <id> --status paused

# Start execution with input
agentled workflows start <id> --input '{"company_url":"https://linkedin.com/company/acme"}'
agentled workflows start <id> --input-file input.json

# Export / Import (cross-environment transfer)
agentled workflows export <id> --output workflow-export.json
agentled workflows import --file workflow-export.json

# Snapshots (automatic versioning on every update)
agentled workflows snapshots <id>
agentled workflows restore <id> <snapshot-id>

# Draft lifecycle (edits to live workflows go to a draft)
agentled workflows draft get <id>
agentled workflows draft promote <id>    # make draft live
agentled workflows draft discard <id>    # throw away draft

# n8n import
agentled workflows import-n8n --file n8n-export.json --preview     # dry-run
agentled workflows import-n8n --file n8n-export.json --name "My Workflow"
```

### Executions

```bash
# List executions for a workflow
agentled executions list <workflow-id>
agentled executions list <workflow-id> --status completed --limit 5

# Get execution details with step results
agentled executions get <workflow-id> <execution-id>

# Stop a running execution
agentled executions stop <workflow-id> <execution-id>

# Pause / Resume an execution
agentled executions pause <workflow-id> <execution-id>
agentled executions resume <workflow-id> <execution-id>
```

### Apps & Actions

```bash
# List available apps/integrations
agentled apps list

# Get action schemas for an app (inputs, outputs, credits)
agentled apps actions <app-id>
# Example: agentled apps actions agentled
# Example: agentled apps actions web-scraping

# Test an action with sample input (no workflow needed)
agentled apps test <app-id> <action-id> --input '{"url":"https://example.com"}'
# Example: agentled apps test web-scraping scrape --input '{"url":"https://example.com"}'
```

### AI Testing

```bash
# Test an AI prompt
agentled ai test --template "Analyze this company: {{company}}" \
  --vars '{"company":"Acme Corp"}'

# With response structure
agentled ai test \
  --template "Score this lead: {{data}}" \
  --vars '{"data":"..."}' \
  --response-structure '{"score":"number 0-100","reasoning":"string"}'
```

### Knowledge Base & Knowledge Graph

```bash
# --- Knowledge Data (DynamoDB lists & text) ---

# List knowledge lists
agentled knowledge lists

# Get rows from a list
agentled knowledge rows <list-key> --limit 50

# Get a text entry
agentled knowledge text <key>

# --- Knowledge Graph (Graphiti) ---

# Traverse edges by entity and/or relationship type
agentled knowledge graph edges
agentled knowledge graph edges --entity "Acme Corp" --relation INVESTED_IN --limit 50

# Fetch scoring history (PROCEED_TO_IC, HOLD_FOR_REVIEW, REPOSITION, SCORED)
agentled knowledge graph scoring
agentled knowledge graph scoring --entity "Acme Corp"
```

### Workspace

```bash
# Get workspace info (name, plan, credits remaining)
agentled workspace info

# Show current saved workspace profile
agentled auth current

# List saved workspace profiles
agentled auth list

# Switch the active workspace profile
agentled auth use <workspace-id|alias|name>

# Get whitelabel branding configuration
agentled workspace branding

# Get editable company profile + offerings
agentled workspace company-profile

# Update company profile fields
agentled workspace update-company-profile --input '{"name":"Acme","urls":["https://acme.com"]}'

# Upsert company offerings
agentled workspace upsert-company-offerings --file offerings.json

# Update branding
agentled workspace update-branding --display-name "Acme" --primary-color "#ff0000"
agentled workspace update-branding --logo-url "https://..." --favicon-url "https://..." --hide-badge
```

---

## 3. Workflow Pipeline Schema

A workflow is a JSON object with this structure:

```json
{
  "name": "Company Research",
  "goal": "Research and score companies from LinkedIn URLs",
  "description": "Detailed description",
  "status": "draft",
  "style": {
    "colors": { "accent": "#6366f1" },
    "iconName": "Search"
  },
  "metadata": {
    "templateId": "custom",
    "notifications": { "onComplete": true }
  },
  "context": {
    "executionInputConfig": {
      "inputPages": [{
        "title": "Input",
        "fields": [
          { "name": "company_url", "label": "Company URL", "type": "text", "required": true }
        ]
      }]
    }
  },
  "steps": [
    { "id": "trigger", "type": "trigger", "name": "Start", "triggerType": "manual", "next": { "stepId": "enrich" } },
    { "id": "enrich", "type": "appAction", "name": "Get Company", "app": { "id": "agentled", "actionId": "get-linkedin-company-from-url", "source": "native" }, "stepInputData": { "profileUrls": "{{input.company_url}}" }, "creditCost": 5, "next": { "stepId": "analyze" } },
    { "id": "analyze", "type": "aiAction", "name": "Analyze", "pipelineStepPrompt": { "template": "Analyze company: {{steps.enrich.company}}", "responseStructure": { "score": "number", "summary": "string" } }, "creditCost": 10, "next": { "stepId": "done" } },
    { "id": "done", "type": "milestone", "name": "Complete" }
  ]
}
```

### Step Types

| Type | Purpose | Required Fields |
|------|---------|----------------|
| `trigger` | Entry point | `triggerType` (manual/schedule/webhook), `next` |
| `appAction` | Call an app integration | `app` ({id, actionId, source}), `stepInputData`, `next` |
| `aiAction` | AI prompt processing | `pipelineStepPrompt` ({template, responseStructure}), `creditCost`, `next` |
| `code` | Run JavaScript/Python | `codeConfig` ({language, code}), `next` |
| `milestone` | Terminal step | (no next) |
| `knowledgeSync` | Remap fields from a prior step + optionally write rows to a KG list + feed knowledgeLink graph edges | `knowledgeSync` ({source.stepId, fieldMapping: {srcField→targetField}, listKey?, source.resultsPath?}), `next` |
| `return` | Return data (child workflows) | `returnConfig`, no next needed |

### Template Variables

| Pattern | Example | Description |
|---------|---------|-------------|
| `{{input.fieldName}}` | `{{input.company_url}}` | Execution input field |
| `{{steps.stepId.field}}` | `{{steps.enrich.company}}` | Previous step output |
| `{{currentItem}}` | `{{currentItem.url}}` | Current item in a loop |
| `{{execution.id}}` | | Current execution ID |
| `{{workspace.id}}` | | Workspace ID |

### Loop Config (for batch processing)

```json
{
  "loopConfig": {
    "enabled": true,
    "field": "{{steps.prev.items}}",
    "ItemAlias": "currentItem"
  }
}
```

### Conditional Entry

> **IMPORTANT**: Entry conditions use `criteria` (NOT `conditions`), and individual criteria use `variable` (NOT `field`). Using the wrong field names will cause conditions to be silently ignored.

```json
{
  "entryConditions": {
    "conditionText": "Only proceed if score is above 50",
    "onCriteriaFail": "skip",
    "criteria": [
      { "variable": "{{steps.prev.score}}", "operator": ">", "value": "50" }
    ]
  }
}
```

---

## 4. Available Apps & Actions

### agentled (Native Enrichment)
| Action | Inputs | Credits |
|--------|--------|---------|
| `get-linkedin-company-from-url` | `{ profileUrls: string }` | 5 |
| `get-linkedin-profile-from-url` | `{ profileUrls: string }` | 2 |
| `find-email-person-domain` | `{ firstName, lastName, domain }` | 3 |
| `get-emails-from-company-domain` | `{ domain: string }` | 5 |
| `call-workflow` | `{ workflowId, input? }` | varies |

### web-scraping
| Action | Inputs | Credits |
|--------|--------|---------|
| `scrape` | `{ url, waitForSelector? }` | 0 |
| `screenshot` | `{ url }` | 0 |

### http-request
| Action | Inputs | Credits |
|--------|--------|---------|
| `request` | `{ url, method?, headers?, body? }` | 0 |
| `get-file` | `{ url }` | 0 |

### hunter
| Action | Inputs | Credits |
|--------|--------|---------|
| `find-email-person-domain` | `{ firstName, lastName, domain }` | 3 |
| `get-emails-from-company-domain` | `{ domain }` | 2 |

### gmail
| Action | Inputs | Credits |
|--------|--------|---------|
| `send-email` | `{ to, subject, body, html? }` | 1 |
| `read-emails` | `{ query?, maxResults? }` | 1 |

### notion
| Action | Inputs | Credits |
|--------|--------|---------|
| `get-page-markdown` | `{ pageUrl }` | 1 |

### kg (Knowledge Graph & Data)
| Action | Inputs | Credits |
|--------|--------|---------|
| `read-list` | `{ listKey, limit? }` | 1 |
| `read-text` | `{ key }` | 1 |
| `add-rows` | `{ listKey, rows: object[] }` | 1 |
| `update-rows` | `{ listKey, rowIds, fieldUpdates, status? }` | 1 |
| `get-rows-by-ids` | `{ rowIds: string[] }` (max 200) | 1 |
| `store-insight` | `{ title, summary, category?, tags?, impactScore?, confidence?, metadata? }` | 1 |
| `fetch-scoring-history` | `(none)` | 1 |
| `traverse-edges` | `{ entityName?, relationshipType?, limit? }` | 1 |

Run `agentled apps list` and `agentled apps actions <app-id>` for full, up-to-date schemas.

---

## 5. Common Patterns

### Pattern 1: Company Intelligence
```bash
# Create a company research workflow
agentled workflows create --pipeline '{
  "name": "Company Research",
  "steps": [
    {"id":"t","type":"trigger","name":"Start","triggerType":"manual","next":{"stepId":"get"}},
    {"id":"get","type":"appAction","name":"Get Company","app":{"id":"agentled","actionId":"get-linkedin-company-from-url","source":"native"},"stepInputData":{"profileUrls":"{{input.url}}"},"creditCost":5,"next":{"stepId":"ai"}},
    {"id":"ai","type":"aiAction","name":"Analyze","pipelineStepPrompt":{"template":"Analyze: {{steps.get.company}}","responseStructure":{"score":"number","summary":"string"}},"creditCost":10,"next":{"stepId":"m"}},
    {"id":"m","type":"milestone","name":"Done"}
  ],
  "context":{"executionInputConfig":{"inputPages":[{"title":"Input","fields":[{"name":"url","label":"LinkedIn URL","type":"text","required":true}]}]}}
}'

# Validate and publish
agentled workflows validate <id>
agentled workflows publish <id> --status live

# Run it
agentled workflows start <id> --input '{"url":"https://linkedin.com/company/acme"}'

# Check results
agentled executions list <id> --limit 1
agentled executions get <id> <exec-id>
```

### Pattern 2: Quick Action Test (No Workflow)
```bash
# Scrape a webpage
agentled apps test web-scraping scrape --input '{"url":"https://example.com"}'

# Find an email
agentled apps test agentled find-email-person-domain --input '{"firstName":"John","lastName":"Doe","domain":"acme.com"}'

# AI analysis
agentled ai test --template "Summarize this content for a sales team: {{content}}" --vars '{"content":"..."}'
```

### Pattern 3: Reusable Workflow (Agent Procedure)
```bash
# Agent creates workflow once
agentled workflows create --file my-research-flow.json
agentled workflows validate abc123
agentled workflows publish abc123 --status live

# Agent reuses on every new lead (one command per lead)
agentled workflows start abc123 --input '{"company_url":"https://..."}'
```

---

## 6. Error Handling

Common validation errors:
- `"references non-existent next step"` → check `next.stepId` matches a real step ID
- `"missing prompt template"` → add `pipelineStepPrompt.template` to AI steps
- `"Unknown action"` → verify `app.actionId` (use `agentled apps actions <app-id>`)
- `"is unreachable"` → ensure every step is connected via `next.stepId` from trigger

CLI exit codes:
- `0` — success
- `1` — error (message printed to stderr)

---

## 7. MCP Server (Alternative)

If you prefer MCP over CLI:

```bash
# Start Agentled as an MCP server over stdio
cd agentled-mcp-server && yarn install && yarn build
claude mcp add agentled -e AGENTLED_API_KEY=wsk_... -- node agentled-mcp-server/dist/index.js
```

The MCP server exposes the same capabilities but loads ~30 tool definitions into your context window.
The CLI approach has zero context cost — the agent just runs shell commands.

---

## 8. Step Approvals

Workflow steps can require human approval before execution via `preExecuteApproval: true` or
`next.conditions.approvalRequired: true` in the pipeline step config. When an execution hits an
approval gate, it pauses and waits for a decision.

**Current state**: Approve/reject is available via the Agentled web UI and internal API.
External API endpoints for programmatic approve/reject are planned.

In the meantime, agents can:
- Check execution status: `agentled executions get <wf-id> <exec-id>` — look for `status: "pending"` timelines
- Pause/resume: `agentled executions pause/resume <wf-id> <exec-id>`

---

## 9. Agent Skills (Open Standard)

Agentled workflows can be packaged as **Agent Skills** — Anthropic's open standard for reusable,
composable AI capabilities. This lets any Agent Skills-compatible tool (Claude Code, Cursor, etc.)
discover and invoke Agentled workflows.

### How It Works

A skill is a markdown file in `.claude/skills/` (or equivalent) that describes a capability and
how to invoke it. Agentled workflows become skills by wrapping the CLI invocation:

```markdown
---
name: research-company
description: Research a company using LinkedIn enrichment, AI analysis, and scoring
---

Use the Agentled CLI to run the company research workflow:

\`\`\`bash
agentled workflows start <workflow-id> --input '{"company_url": "$ARGUMENTS"}'
\`\`\`

Check results with:
\`\`\`bash
agentled executions list <workflow-id> --limit 1
agentled executions get <workflow-id> <exec-id>
\`\`\`
```

### Key Properties

- **Composable**: Multiple skills (workflows) can chain together — one skill's output feeds another
- **Portable**: Same skill file works in Claude Code, Cursor, and any Agent Skills-compatible tool
- **Zero context cost**: Skills load a short description; the actual logic runs via CLI
- **Auto-invocable**: Claude can automatically match user intent to skills based on descriptions

### Agentled + Skills = Agent Infrastructure

Instead of an agent making 15 individual API calls, it invokes one Agentled skill that orchestrates
the entire multi-step workflow (enrichment, AI analysis, scoring, CRM sync). The workflow handles
retries, rate limits, credit management, and data persistence — the agent just reads the result.
