{
  "name": "REVOPS-LI-006 | 03 | HubSpot attribution property setup",
  "nodes": [
    {
      "parameters": {},
      "id": "a8590a9f-51ed-4831-8896-d1fa817a73de",
      "name": "Setup Properties",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "return [{\"name\":\"revops_original_source\",\"label\":\"RevOps original source\",\"type\":\"enumeration\",\"fieldType\":\"select\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\",\"options\":[{\"label\":\"PAID_SEARCH\",\"value\":\"PAID_SEARCH\",\"displayOrder\":0,\"hidden\":false},{\"label\":\"ORGANIC_SEARCH\",\"value\":\"ORGANIC_SEARCH\",\"displayOrder\":1,\"hidden\":false},{\"label\":\"PAID_SOCIAL\",\"value\":\"PAID_SOCIAL\",\"displayOrder\":2,\"hidden\":false},{\"label\":\"ORGANIC_SOCIAL\",\"value\":\"ORGANIC_SOCIAL\",\"displayOrder\":3,\"hidden\":false},{\"label\":\"DIRECT_TRAFFIC\",\"value\":\"DIRECT_TRAFFIC\",\"displayOrder\":4,\"hidden\":false},{\"label\":\"REFERRAL\",\"value\":\"REFERRAL\",\"displayOrder\":5,\"hidden\":false},{\"label\":\"EMAIL\",\"value\":\"EMAIL\",\"displayOrder\":6,\"hidden\":false},{\"label\":\"EVENT\",\"value\":\"EVENT\",\"displayOrder\":7,\"hidden\":false},{\"label\":\"PARTNER\",\"value\":\"PARTNER\",\"displayOrder\":8,\"hidden\":false},{\"label\":\"OUTBOUND\",\"value\":\"OUTBOUND\",\"displayOrder\":9,\"hidden\":false},{\"label\":\"WEBINAR\",\"value\":\"WEBINAR\",\"displayOrder\":10,\"hidden\":false},{\"label\":\"MANUAL_IMPORT\",\"value\":\"MANUAL_IMPORT\",\"displayOrder\":11,\"hidden\":false},{\"label\":\"INTEGRATION\",\"value\":\"INTEGRATION\",\"displayOrder\":12,\"hidden\":false},{\"label\":\"DISPLAY\",\"value\":\"DISPLAY\",\"displayOrder\":13,\"hidden\":false},{\"label\":\"VIDEO\",\"value\":\"VIDEO\",\"displayOrder\":14,\"hidden\":false},{\"label\":\"PAID_VIDEO\",\"value\":\"PAID_VIDEO\",\"displayOrder\":15,\"hidden\":false},{\"label\":\"AFFILIATE\",\"value\":\"AFFILIATE\",\"displayOrder\":16,\"hidden\":false},{\"label\":\"CROSS_NETWORK\",\"value\":\"CROSS_NETWORK\",\"displayOrder\":17,\"hidden\":false},{\"label\":\"UNKNOWN\",\"value\":\"UNKNOWN\",\"displayOrder\":18,\"hidden\":false}]},{\"name\":\"revops_original_source_detail\",\"label\":\"RevOps original source detail\",\"type\":\"string\",\"fieldType\":\"text\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_latest_source\",\"label\":\"RevOps latest source\",\"type\":\"enumeration\",\"fieldType\":\"select\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\",\"options\":[{\"label\":\"PAID_SEARCH\",\"value\":\"PAID_SEARCH\",\"displayOrder\":0,\"hidden\":false},{\"label\":\"ORGANIC_SEARCH\",\"value\":\"ORGANIC_SEARCH\",\"displayOrder\":1,\"hidden\":false},{\"label\":\"PAID_SOCIAL\",\"value\":\"PAID_SOCIAL\",\"displayOrder\":2,\"hidden\":false},{\"label\":\"ORGANIC_SOCIAL\",\"value\":\"ORGANIC_SOCIAL\",\"displayOrder\":3,\"hidden\":false},{\"label\":\"DIRECT_TRAFFIC\",\"value\":\"DIRECT_TRAFFIC\",\"displayOrder\":4,\"hidden\":false},{\"label\":\"REFERRAL\",\"value\":\"REFERRAL\",\"displayOrder\":5,\"hidden\":false},{\"label\":\"EMAIL\",\"value\":\"EMAIL\",\"displayOrder\":6,\"hidden\":false},{\"label\":\"EVENT\",\"value\":\"EVENT\",\"displayOrder\":7,\"hidden\":false},{\"label\":\"PARTNER\",\"value\":\"PARTNER\",\"displayOrder\":8,\"hidden\":false},{\"label\":\"OUTBOUND\",\"value\":\"OUTBOUND\",\"displayOrder\":9,\"hidden\":false},{\"label\":\"WEBINAR\",\"value\":\"WEBINAR\",\"displayOrder\":10,\"hidden\":false},{\"label\":\"MANUAL_IMPORT\",\"value\":\"MANUAL_IMPORT\",\"displayOrder\":11,\"hidden\":false},{\"label\":\"INTEGRATION\",\"value\":\"INTEGRATION\",\"displayOrder\":12,\"hidden\":false},{\"label\":\"DISPLAY\",\"value\":\"DISPLAY\",\"displayOrder\":13,\"hidden\":false},{\"label\":\"VIDEO\",\"value\":\"VIDEO\",\"displayOrder\":14,\"hidden\":false},{\"label\":\"PAID_VIDEO\",\"value\":\"PAID_VIDEO\",\"displayOrder\":15,\"hidden\":false},{\"label\":\"AFFILIATE\",\"value\":\"AFFILIATE\",\"displayOrder\":16,\"hidden\":false},{\"label\":\"CROSS_NETWORK\",\"value\":\"CROSS_NETWORK\",\"displayOrder\":17,\"hidden\":false},{\"label\":\"UNKNOWN\",\"value\":\"UNKNOWN\",\"displayOrder\":18,\"hidden\":false}]},{\"name\":\"revops_latest_source_detail\",\"label\":\"RevOps latest source detail\",\"type\":\"string\",\"fieldType\":\"text\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_first_touch_at\",\"label\":\"RevOps first_touch_at\",\"type\":\"datetime\",\"fieldType\":\"date\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_latest_touch_at\",\"label\":\"RevOps latest_touch_at\",\"type\":\"datetime\",\"fieldType\":\"date\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_source_last_updated_at\",\"label\":\"RevOps source_last_updated_at\",\"type\":\"datetime\",\"fieldType\":\"date\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_utm_source\",\"label\":\"RevOps utm_source\",\"type\":\"string\",\"fieldType\":\"text\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_utm_medium\",\"label\":\"RevOps utm_medium\",\"type\":\"string\",\"fieldType\":\"text\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_utm_campaign\",\"label\":\"RevOps utm_campaign\",\"type\":\"string\",\"fieldType\":\"text\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_utm_content\",\"label\":\"RevOps utm_content\",\"type\":\"string\",\"fieldType\":\"text\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_utm_term\",\"label\":\"RevOps utm_term\",\"type\":\"string\",\"fieldType\":\"text\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_utm_id\",\"label\":\"RevOps utm_id\",\"type\":\"string\",\"fieldType\":\"text\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_landing_page_url\",\"label\":\"RevOps landing_page_url\",\"type\":\"string\",\"fieldType\":\"text\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_conversion_page_url\",\"label\":\"RevOps conversion_page_url\",\"type\":\"string\",\"fieldType\":\"text\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_referrer_url\",\"label\":\"RevOps referrer_url\",\"type\":\"string\",\"fieldType\":\"text\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_form_id\",\"label\":\"RevOps form_id\",\"type\":\"string\",\"fieldType\":\"text\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_form_name\",\"label\":\"RevOps form_name\",\"type\":\"string\",\"fieldType\":\"text\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_conversion_event_name\",\"label\":\"RevOps conversion_event_name\",\"type\":\"string\",\"fieldType\":\"text\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_last_submission_id\",\"label\":\"RevOps last_submission_id\",\"type\":\"string\",\"fieldType\":\"text\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\"},{\"name\":\"revops_attribution_status\",\"label\":\"RevOps attribution status\",\"type\":\"enumeration\",\"fieldType\":\"select\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\",\"options\":[{\"label\":\"ATTRIBUTION_COMPLETE\",\"value\":\"ATTRIBUTION_COMPLETE\",\"displayOrder\":0,\"hidden\":false},{\"label\":\"ATTRIBUTION_PARTIAL\",\"value\":\"ATTRIBUTION_PARTIAL\",\"displayOrder\":1,\"hidden\":false},{\"label\":\"ATTRIBUTION_INCOMPLETE\",\"value\":\"ATTRIBUTION_INCOMPLETE\",\"displayOrder\":2,\"hidden\":false},{\"label\":\"ATTRIBUTION_UNKNOWN\",\"value\":\"ATTRIBUTION_UNKNOWN\",\"displayOrder\":3,\"hidden\":false},{\"label\":\"ATTRIBUTION_CONFLICT\",\"value\":\"ATTRIBUTION_CONFLICT\",\"displayOrder\":4,\"hidden\":false}]},{\"name\":\"revops_source_cleanup_status\",\"label\":\"RevOps source cleanup status\",\"type\":\"enumeration\",\"fieldType\":\"select\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\",\"options\":[{\"label\":\"NORMALIZED\",\"value\":\"NORMALIZED\",\"displayOrder\":0,\"hidden\":false},{\"label\":\"TIMESTAMP_INFERRED\",\"value\":\"TIMESTAMP_INFERRED\",\"displayOrder\":1,\"hidden\":false},{\"label\":\"HISTORY_ONLY\",\"value\":\"HISTORY_ONLY\",\"displayOrder\":2,\"hidden\":false},{\"label\":\"REVIEW_REQUIRED\",\"value\":\"REVIEW_REQUIRED\",\"displayOrder\":3,\"hidden\":false}]},{\"name\":\"revops_attribution_locked\",\"label\":\"RevOps attribution_locked\",\"type\":\"bool\",\"fieldType\":\"booleancheckbox\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\",\"options\":[{\"label\":\"true\",\"value\":\"true\",\"displayOrder\":0,\"hidden\":false},{\"label\":\"false\",\"value\":\"false\",\"displayOrder\":1,\"hidden\":false}]},{\"name\":\"revops_source_conflict_flag\",\"label\":\"RevOps source_conflict_flag\",\"type\":\"bool\",\"fieldType\":\"booleancheckbox\",\"groupName\":\"contactinformation\",\"description\":\"REVOPS-LI-006 attribution governance\",\"options\":[{\"label\":\"true\",\"value\":\"true\",\"displayOrder\":0,\"hidden\":false},{\"label\":\"false\",\"value\":\"false\",\"displayOrder\":1,\"hidden\":false}]}].map(property=>({json:{property}}));"
      },
      "id": "f2448690-c742-489f-9bbb-848e9ecebbd4",
      "name": "Definitions",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        270,
        0
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "={{ 'https://api.hubapi.com/crm/v3/properties/contacts/'+$json.property.name }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 30000,
          "response": {
            "response": {
              "fullResponse": true,
              "neverError": true,
              "responseFormat": "json"
            }
          }
        }
      },
      "id": "6a666aa1-c5b4-4c31-b304-aeba7e6d2505",
      "name": "Read Property Definition",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        540,
        0
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE_HUBSPOT_CREDENTIAL",
          "name": "ATTRIBUTION HubSpot"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "return $input.all().map((item,i)=>{const p=$('Definitions').all()[i].json.property;const r=item.json;if(![200,404].includes(r.statusCode))throw new Error('Property lookup failed: '+p.name);if(r.statusCode===200){if(r.body.type!==p.type||r.body.fieldType!==p.fieldType)throw new Error('Incompatible property '+p.name);for(const option of p.options||[])if(!(r.body.options||[]).some(o=>o.value===option.value))throw new Error('Missing enum option '+option.value+' on '+p.name)}return {json:{property:p,missing:r.statusCode===404},pairedItem:{item:i}}});"
      },
      "id": "2cef14e9-4d87-442e-a475-2c1b9f068a7e",
      "name": "Check Existing Definition",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        810,
        0
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "f29490f0-61bc-4bb2-9968-2ab2386717a2",
              "leftValue": "={{ $json.missing === true }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "7000e74d-0620-4b9b-a434-fecc4fcb5aad",
      "name": "Missing Property?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1080,
        0
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.hubapi.com/crm/v3/properties/contacts",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "contentType": "json",
        "specifyBody": "json",
        "jsonBody": "={{ $json.property }}",
        "options": {
          "timeout": 30000
        }
      },
      "id": "a68ae61d-cb05-4871-bb53-b2f018776091",
      "name": "Create Missing Property",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1350,
        0
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE_HUBSPOT_CREDENTIAL",
          "name": "ATTRIBUTION HubSpot"
        }
      }
    },
    {
      "parameters": {
        "content": "## One-time property setup\nOnly custom revops_ properties are written. HubSpot native analytics source fields remain untouched.\nCreates missing definitions; incompatible existing types/options fail for review.\nThe shared revops_last_submission_id string is compatible with REVOPS-L1-001.",
        "width": 700,
        "height": 220
      },
      "id": "b79d0c7f-6fe3-4b0f-93a0-a5bf02bbed3e",
      "name": "Workflow Guide",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        -270
      ]
    }
  ],
  "connections": {
    "Setup Properties": {
      "main": [
        [
          {
            "node": "Definitions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Definitions": {
      "main": [
        [
          {
            "node": "Read Property Definition",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Property Definition": {
      "main": [
        [
          {
            "node": "Check Existing Definition",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Existing Definition": {
      "main": [
        [
          {
            "node": "Missing Property?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Missing Property?": {
      "main": [
        [
          {
            "node": "Create Missing Property",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "timezone": "Asia/Tbilisi",
    "saveExecutionProgress": true
  },
  "active": false,
  "pinData": {},
  "tags": []
}

