{
  "name": "blue·auth · Signature (send + receive events)",
  "meta": {
    "templateCreatedBy": "blue·auth",
    "description": "Sends a document for signature through the blue·auth API and receives events (signature.sent/signed/declined/cancelled/completed) in a webhook, validating the HMAC signature and branching by event type."
  },
  "nodes": [
    {
      "parameters": {},
      "id": "trigger-manual",
      "name": "When clicking Test workflow",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        240,
        240
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://blueauth.co/api/v1/signature-requests",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"documentName\": \"Contract.pdf\",\n  \"pdfBase64\": \"data:application/pdf;base64,REPLACE_WITH_BASE64\",\n  \"webhookUrl\": \"={{ $json.webhookUrl || 'https://your-n8n.example/webhook/blueauth' }}\",\n  \"signers\": [\n    { \"email\": \"me@company.example\", \"fullName\": \"My Company\", \"idNumber\": \"123456789\", \"selfSign\": true, \"signatureMethod\": \"traditional\", \"zones\": [{ \"page\": 1, \"x\": 60, \"y\": 700, \"width\": 180, \"height\": 60, \"type\": \"signature\" }] },\n    { \"email\": \"customer@example.com\", \"fullName\": \"Final Customer\", \"idNumber\": \"987654321\", \"signatureMethod\": \"traditional\", \"zones\": [{ \"page\": 1, \"x\": 330, \"y\": 700, \"width\": 180, \"height\": 60, \"type\": \"signature\" }] }\n  ]\n}",
        "options": {}
      },
      "id": "http-create",
      "name": "Send for signature",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        480,
        240
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE",
          "name": "BlueAuth API Key (Authorization: Bearer ba_live_…)"
        }
      }
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "blueauth",
        "options": {
          "rawBody": true
        }
      },
      "id": "webhook-events",
      "name": "Receive blue·auth events",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        240,
        540
      ],
      "webhookId": "blueauth-events"
    },
    {
      "parameters": {
        "jsCode": "// Validate the blue·auth webhook HMAC signature before trusting the event.\n// Set WEBHOOK_SECRET to the webhookSecret returned when the request was created.\nconst crypto = require('crypto');\nconst WEBHOOK_SECRET = $env.BLUEAUTH_WEBHOOK_SECRET || 'whsig_REPLACE';\nconst raw = $input.first().binary ? '' : JSON.stringify($input.first().json.body ?? $input.first().json);\nconst header = ($input.first().json.headers || {})['x-blueauth-signature'] || '';\nconst expected = crypto.createHmac('sha256', WEBHOOK_SECRET).update(raw, 'utf8').digest('hex');\nconst valid = header && expected.length === header.length && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(header));\nconst event = ($input.first().json.headers || {})['x-blueauth-event'] || ($input.first().json.body || {}).event;\nreturn [{ json: { valid, event, payload: $input.first().json.body ?? $input.first().json } }];"
      },
      "id": "verify-hmac",
      "name": "Verify HMAC",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        480,
        540
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.event }}",
                    "rightValue": "signature.signed",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ]
              },
              "outputKey": "signed"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.event }}",
                    "rightValue": "signature.completed",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ]
              },
              "outputKey": "completed"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.event }}",
                    "rightValue": "signature.declined",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ]
              },
              "outputKey": "declined"
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "id": "switch-event",
      "name": "Branch by event",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3,
      "position": [
        720,
        540
      ]
    },
    {
      "parameters": {
        "content": "## ⚙️ Setup\n• Add a **Header Auth** credential to the HTTP node: `Authorization` = `Bearer ba_…`.\n• Copy the webhook **Production URL** (`/webhook/…`) and paste it into the send request's `webhookUrl`.\n• Set the workflow to **Active** and add your `pdfBase64` to the send request.",
        "height": 170,
        "width": 900,
        "color": 7
      },
      "id": "note-setup",
      "name": "Sticky · Setup",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        200,
        20
      ]
    },
    {
      "parameters": {
        "content": "## 🟦 Send\nCreates the request. Signers without `selfSign` receive the signing link by email.",
        "height": 200,
        "width": 520,
        "color": 5
      },
      "id": "note-send",
      "name": "Sticky · Send",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        200,
        200
      ]
    },
    {
      "parameters": {
        "content": "## 🟩 Receive events\nWebhook → Verify HMAC → Switch by `X-BlueAuth-Event`.",
        "height": 230,
        "width": 760,
        "color": 4
      },
      "id": "note-recv",
      "name": "Sticky · Receive",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        200,
        470
      ]
    }
  ],
  "connections": {
    "When clicking Test workflow": {
      "main": [
        [
          {
            "node": "Send for signature",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Receive blue·auth events": {
      "main": [
        [
          {
            "node": "Verify HMAC",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verify HMAC": {
      "main": [
        [
          {
            "node": "Branch by event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  }
}
