{
  "name": "Nodbot - Anthropic Claude JSON workflow with guardrails",
  "nodes": [
    {
      "parameters": {
        "path": "integration-anthropic-claude-n8n",
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "id": "d61ecb20-2ac9-4586-bb68-21e0bf6cb053",
      "name": "Webhook AI task",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        0,
        260
      ]
    },
    {
      "parameters": {
        "jsCode": "const src = $json.body ?? $json;\nconst text = String(src.text ?? '').replace(/\\s+/g, ' ').trim();\nif (text.length < 30) throw new Error('Text is too short for Claude triage');\nconst allowedLabels = Array.isArray(src.allowed_labels) ? src.allowed_labels : ['other'];\nconst allowedActions = Array.isArray(src.allowed_actions) ? src.allowed_actions : ['human_review'];\nconst minConfidence = Number(src.min_confidence ?? 0.8);\nconst maxInputChars = Number($env.CLAUDE_MAX_INPUT_CHARS ?? 12000);\nreturn [{ json: {\n  request_id: String(src.request_id ?? crypto.randomUUID()),\n  anthropic: {\n    model: $env.CLAUDE_MODEL ?? 'claude-3-5-sonnet-latest',\n    max_tokens: Number($env.CLAUDE_MAX_TOKENS ?? 700),\n    messages: [{ role: 'user', content: text.slice(0, maxInputChars) }],\n    system: `Return only JSON: {\"label\":\"one of ${allowedLabels.join('|')}\",\"confidence\":0..1,\"action\":\"one of ${allowedActions.join('|')}\",\"summary\":\"short ru\"}. No markdown.`\n  },\n  validation: { allowedLabels, allowedActions, minConfidence }\n}}];"
      },
      "id": "4b43f2b1-50b1-44d8-b933-130ab91ccf2c",
      "name": "Prepare Claude prompt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        280,
        260
      ]
    },
    {
      "parameters": {},
      "id": "16c44d4b-693b-4ef8-a3b2-168f0e7b3a6f",
      "name": "Call Anthropic Messages API",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 2,
      "position": [
        560,
        260
      ]
    },
    {
      "parameters": {
        "jsCode": "const src = $json.body ?? $json;\nconst text = String(src.text ?? '').replace(/\\s+/g, ' ').trim();\nif (text.length < 30) throw new Error('Text is too short for Claude triage');\nconst allowedLabels = Array.isArray(src.allowed_labels) ? src.allowed_labels : ['other'];\nconst allowedActions = Array.isArray(src.allowed_actions) ? src.allowed_actions : ['human_review'];\nconst minConfidence = Number(src.min_confidence ?? 0.8);\nconst maxInputChars = Number($env.CLAUDE_MAX_INPUT_CHARS ?? 12000);\nreturn [{ json: {\n  request_id: String(src.request_id ?? crypto.randomUUID()),\n  anthropic: {\n    model: $env.CLAUDE_MODEL ?? 'claude-3-5-sonnet-latest',\n    max_tokens: Number($env.CLAUDE_MAX_TOKENS ?? 700),\n    messages: [{ role: 'user', content: text.slice(0, maxInputChars) }],\n    system: `Return only JSON: {\"label\":\"one of ${allowedLabels.join('|')}\",\"confidence\":0..1,\"action\":\"one of ${allowedActions.join('|')}\",\"summary\":\"short ru\"}. No markdown.`\n  },\n  validation: { allowedLabels, allowedActions, minConfidence }\n}}];"
      },
      "id": "5d84946d-a7da-4e20-a8c3-f21afd8b7bc6",
      "name": "Validate Claude JSON",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        840,
        260
      ]
    },
    {
      "parameters": {
        "jsCode": "const src = $json.body ?? $json;\nconst text = String(src.text ?? '').replace(/\\s+/g, ' ').trim();\nif (text.length < 30) throw new Error('Text is too short for Claude triage');\nconst allowedLabels = Array.isArray(src.allowed_labels) ? src.allowed_labels : ['other'];\nconst allowedActions = Array.isArray(src.allowed_actions) ? src.allowed_actions : ['human_review'];\nconst minConfidence = Number(src.min_confidence ?? 0.8);\nconst maxInputChars = Number($env.CLAUDE_MAX_INPUT_CHARS ?? 12000);\nreturn [{ json: {\n  request_id: String(src.request_id ?? crypto.randomUUID()),\n  anthropic: {\n    model: $env.CLAUDE_MODEL ?? 'claude-3-5-sonnet-latest',\n    max_tokens: Number($env.CLAUDE_MAX_TOKENS ?? 700),\n    messages: [{ role: 'user', content: text.slice(0, maxInputChars) }],\n    system: `Return only JSON: {\"label\":\"one of ${allowedLabels.join('|')}\",\"confidence\":0..1,\"action\":\"one of ${allowedActions.join('|')}\",\"summary\":\"short ru\"}. No markdown.`\n  },\n  validation: { allowedLabels, allowedActions, minConfidence }\n}}];"
      },
      "id": "fb3d44e7-5e9e-4bd6-8270-1d3e47e03e56",
      "name": "Route review or action",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1120,
        260
      ]
    },
    {
      "parameters": {},
      "id": "54d33721-4776-4c1f-be09-213c161a5756",
      "name": "Respond",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 2,
      "position": [
        1400,
        260
      ]
    }
  ],
  "connections": {
    "Webhook AI task": {
      "main": [
        [
          {
            "node": "Prepare Claude prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Claude prompt": {
      "main": [
        [
          {
            "node": "Call Anthropic Messages API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Call Anthropic Messages API": {
      "main": [
        [
          {
            "node": "Validate Claude JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Claude JSON": {
      "main": [
        [
          {
            "node": "Route review or action",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route review or action": {
      "main": [
        [
          {
            "node": "Respond",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "tags": [
    "nodbot",
    "integration",
    "production"
  ],
  "triggerCount": 1,
  "updatedAt": "2026-05-30T00:00:00.000Z",
  "versionId": "95aac42e-281f-49a7-ba8c-7ef004525eca",
  "meta": {
    "templateCredsSetupCompleted": false
  }
}