{
  "name": "Enrich HubSpot contacts with QuietPass and recover failed CRM writes",
  "active": false,
  "nodes": [
    {
      "id": "start-manually",
      "name": "Start manually",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        0
      ],
      "parameters": {}
    },
    {
      "id": "configuration",
      "name": "Configuration",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        280,
        0
      ],
      "parameters": {
        "mode": "raw",
        "jsonOutput": "{\"contactId\":\"REPLACE_CONTACT_ID\",\"portalId\":\"REPLACE_HUBSPOT_PORTAL_ID\",\"defaultCountry\":\"\",\"allowPaid\":false,\"maximumMicros\":0,\"checks\":[\"basic_line_type\",\"enhanced_line_type\",\"current_carrier\",\"mnp\",\"live_status\",\"sms\",\"whatsapp\",\"telegram\"]}",
        "options": {}
      }
    },
    {
      "id": "validate-configuration",
      "name": "Validate configuration",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        560,
        0
      ],
      "parameters": {
        "jsCode": "const c=$json; if(!/^[1-9][0-9]{0,25}$/.test(c.contactId)||!/^[1-9][0-9]{0,25}$/.test(c.portalId)) throw Error('Replace both IDs in Configuration. Use a trusted upstream contact event when automating.'); return [{json:c}];"
      }
    },
    {
      "id": "read-hubspot-account",
      "name": "Read HubSpot account",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        840,
        0
      ],
      "parameters": {
        "method": "GET",
        "url": "https://api.hubapi.com/account-info/v3/details",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "hubspotAppToken",
        "options": {
          "redirect": {
            "redirect": {
              "followRedirects": false
            }
          },
          "timeout": 10000,
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      }
    },
    {
      "id": "verify-hubspot-account",
      "name": "Verify HubSpot account",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1120,
        0
      ],
      "parameters": {
        "jsCode": "if(String($json.portalId)!==$('Configuration').first().json.portalId)throw Error('The HubSpot credential belongs to another portal.');return [{json:$json}];"
      }
    },
    {
      "id": "read-source-contact",
      "name": "Read source contact",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1400,
        0
      ],
      "parameters": {
        "method": "GET",
        "url": "={{ \"https://api.hubapi.com/crm/v3/objects/contacts/\" + $(\"Configuration\").first().json.contactId + \"?properties=phone,hs_country_region_code,qp_phone_request_id&propertiesWithHistory=phone\" }}",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "hubspotAppToken",
        "options": {
          "redirect": {
            "redirect": {
              "followRedirects": false
            }
          },
          "timeout": 10000,
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      }
    },
    {
      "id": "source-identity",
      "name": "Source identity",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1680,
        0
      ],
      "parameters": {
        "jsCode": "function phoneRevision(contact){\n const history=contact.propertiesWithHistory?.phone;\n if(!Array.isArray(history)||!history.length)return null;\n const sorted=history.filter(v=>typeof v.timestamp==='string'&&Number.isFinite(Date.parse(v.timestamp))).sort((a,b)=>Date.parse(b.timestamp)-Date.parse(a.timestamp));\n return sorted[0]?.timestamp??null;\n}\nfunction contactIdentity(contact,config){\n if(!/^[1-9][0-9]{0,25}$/.test(config.contactId)||!/^[1-9][0-9]{0,25}$/.test(config.portalId)||String(contact.id)!==config.contactId||contact.archived===true)throw Error('Check the contact ID and HubSpot credential account.');\n const revision=phoneRevision(contact),phone=contact.properties?.phone;\n return {contactId:config.contactId,revision,phone:typeof phone==='string'?phone:'',country:contact.properties?.hs_country_region_code||config.defaultCountry||'',needsReview:!revision||!phone,reason:!phone?'empty_phone':!revision?'phone_history_required':null};\n}\nreturn [{json:contactIdentity($json,$('Configuration').first().json)}];"
      }
    },
    {
      "id": "has-phone-history",
      "name": "Has phone history",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        0,
        440
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "Has phone history",
              "leftValue": "={{ $json.needsReview === false }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "format-source-phone",
      "name": "Format source phone",
      "type": "n8n-nodes-quietpass.quietPass",
      "typeVersion": 1,
      "position": [
        280,
        440
      ],
      "parameters": {
        "resource": "phoneNumber",
        "operation": "format",
        "phone": "={{ $json.phone }}",
        "defaultCountry": "={{ $json.country }}",
        "options": {}
      },
      "onError": "continueRegularOutput"
    },
    {
      "id": "valid-source-phone",
      "name": "Valid source phone",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        560,
        440
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "Valid source phone",
              "leftValue": "={{ $json.number?.valid === true }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "read-workspace-limits",
      "name": "Read workspace limits",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        840,
        440
      ],
      "parameters": {
        "method": "GET",
        "url": "https://quietpass.com/v1/automation/settings",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "quietPassApi",
        "options": {
          "redirect": {
            "redirect": {
              "followRedirects": false
            }
          },
          "timeout": 10000,
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      }
    },
    {
      "id": "spending-permission",
      "name": "Spending permission",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1120,
        440
      ],
      "parameters": {
        "jsCode": "function spendingGate(config,limits){\n if(typeof config.allowPaid!=='boolean'||!Number.isSafeInteger(config.maximumMicros)||config.maximumMicros<0||config.maximumMicros>1000000||!Array.isArray(config.checks)||!config.checks.length||config.checks.some(c=>!['basic_line_type','enhanced_line_type','current_carrier','mnp','live_status','sms','whatsapp','telegram'].includes(c)))throw Error('Review the workflow checks and spending ceiling.');\n const paid=config.checks.some(c=>c!=='basic_line_type');\n const reason=limits.available!==true?'workflow_access_unavailable':limits.enabled!==true?'purchases_paused':!['GBP','USD','EUR'].includes(limits.currency)?'currency_unavailable':paid&&config.allowPaid!==true?'paid_use_disabled':paid&&config.maximumMicros===0?'zero_spending_ceiling':config.maximumMicros>limits.maximumMicros?'workspace_ceiling_exceeded':null;\n return {allowed:reason===null,reason,currency:limits.currency,maximumMicros:config.maximumMicros};\n}\nreturn [{json:spendingGate($('Configuration').first().json,$json)}];"
      }
    },
    {
      "id": "purchases-allowed",
      "name": "Purchases allowed",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1400,
        440
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "Purchases allowed",
              "leftValue": "={{ $json.allowed === true }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "prepare-saved-operation",
      "name": "Prepare saved operation",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1680,
        440
      ],
      "parameters": {
        "method": "POST",
        "url": "https://quietpass.com/v1/automation/operations",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "quietPassApi",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ workflowId:\"n8n:hubspot:\"+$(\"Configuration\").first().json.portalId+\":phone-v1\", recordId:$(\"Source identity\").first().json.contactId, revision:$(\"Source identity\").first().json.revision, phone:$(\"Format source phone\").first().json.number.e164, checks:$(\"Configuration\").first().json.checks, currency:$(\"Spending permission\").first().json.currency, maximumMicros:$(\"Configuration\").first().json.maximumMicros }) }}",
        "options": {
          "redirect": {
            "redirect": {
              "followRedirects": false
            }
          },
          "timeout": 10000,
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      }
    },
    {
      "id": "run-original-operation",
      "name": "Run original operation",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        0,
        880
      ],
      "parameters": {
        "method": "POST",
        "url": "={{ \"https://quietpass.com/v1/automation/operations/\" + $json.id + \"/run\" }}",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "quietPassApi",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({allowPaid:$(\"Configuration\").first().json.allowPaid}) }}",
        "options": {
          "redirect": {
            "redirect": {
              "followRedirects": false
            }
          },
          "timeout": 10000,
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      }
    },
    {
      "id": "read-retained-result",
      "name": "Read retained result",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        280,
        880
      ],
      "parameters": {
        "method": "GET",
        "url": "={{ \"https://quietpass.com/v1/automation/operations/\" + $(\"Prepare saved operation\").first().json.id }}",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "quietPassApi",
        "options": {
          "redirect": {
            "redirect": {
              "followRedirects": false
            }
          },
          "timeout": 10000,
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      }
    },
    {
      "id": "result-is-settled",
      "name": "Result is settled",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        560,
        880
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "Result is settled",
              "leftValue": "={{ $json.state === \"settled\" && $json.resultState === \"settled\" && !!$json.result?.requestId }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "read-current-contact",
      "name": "Read current contact",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        840,
        880
      ],
      "parameters": {
        "method": "GET",
        "url": "={{ \"https://api.hubapi.com/crm/v3/objects/contacts/\" + $(\"Configuration\").first().json.contactId + \"?properties=phone,hs_country_region_code,qp_phone_request_id&propertiesWithHistory=phone\" }}",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "hubspotAppToken",
        "options": {
          "redirect": {
            "redirect": {
              "followRedirects": false
            }
          },
          "timeout": 10000,
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      }
    },
    {
      "id": "format-current-phone",
      "name": "Format current phone",
      "type": "n8n-nodes-quietpass.quietPass",
      "typeVersion": 1,
      "position": [
        1120,
        880
      ],
      "parameters": {
        "resource": "phoneNumber",
        "operation": "format",
        "phone": "={{ $json.properties.phone || \"\" }}",
        "defaultCountry": "={{ $json.properties.hs_country_region_code || $(\"Configuration\").first().json.defaultCountry }}",
        "options": {}
      },
      "onError": "continueRegularOutput"
    },
    {
      "id": "guard-current-source",
      "name": "Guard current source",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1400,
        880
      ],
      "parameters": {
        "jsCode": "function phoneRevision(contact){\n const history=contact.propertiesWithHistory?.phone;\n if(!Array.isArray(history)||!history.length)return null;\n const sorted=history.filter(v=>typeof v.timestamp==='string'&&Number.isFinite(Date.parse(v.timestamp))).sort((a,b)=>Date.parse(b.timestamp)-Date.parse(a.timestamp));\n return sorted[0]?.timestamp??null;\n}\nfunction retainedResult(operation){\n const r=operation?.result;\n return operation?.state==='settled'&&operation.resultState==='settled'&&typeof r?.requestId==='string'&&r.number?.valid===true&&typeof r.number.e164==='string';\n}\nfunction writeGuard(contact,formatted,operation,identity){\n const reason=!retainedResult(operation)?'result_not_ready':String(contact.id)!==identity.contactId?'contact_changed':phoneRevision(contact)!==identity.revision?'source_revision_changed':formatted.number?.valid!==true||formatted.number.e164!==operation.result.number.e164?'source_phone_changed':contact.properties?.qp_phone_request_id===operation.result.requestId?'already_written':null;\n if(reason)return {write:false,reason,operationId:operation.id};\n const r=operation.result,s=r.contact?.sms??{},scalar=v=>typeof v==='boolean'?String(v):typeof v==='string'?v.slice(0,300):'';\n const reasons=[r.number.validationReason,r.number.typeReason,r.number.carrierReason,r.number.portedReason,s.reason,r.contact?.whatsapp?.reason,r.contact?.telegram?.reason,r.network?.reason].filter(v=>typeof v==='string');\n const fields={e164:r.number.e164,country:r.number.country,valid:r.number.valid,type:r.number.type,carrier:r.number.carrier,ported:r.number.ported,sms:s.supported,sms_basis:s.basis,whatsapp:r.contact?.whatsapp?.registered,telegram:r.contact?.telegram?.registered,reachable:r.network?.reachable,status:reasons.length?'partial':'completed',reason:[...new Set(reasons)].join('; '),checked_at:r.preparedAt,request_id:r.requestId};\n return {write:true,operationId:operation.id,requestId:r.requestId,contactId:identity.contactId,revision:identity.revision,properties:Object.fromEntries(Object.entries(fields).map(([k,v])=>['qp_phone_'+k,scalar(v)]))};\n}\nreturn [{json:writeGuard($('Read current contact').first().json,$json,$('Read retained result').first().json,$('Source identity').first().json)}];"
      }
    },
    {
      "id": "safe-to-write",
      "name": "Safe to write",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1680,
        880
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "Safe to write",
              "leftValue": "={{ $json.write === true }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "write-quietpass-fields",
      "name": "Write QuietPass fields",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        0,
        1320
      ],
      "parameters": {
        "method": "PATCH",
        "url": "={{ \"https://api.hubapi.com/crm/v3/objects/contacts/\" + $json.contactId }}",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "hubspotAppToken",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({properties:$json.properties}) }}",
        "options": {
          "redirect": {
            "redirect": {
              "followRedirects": false
            }
          },
          "timeout": 10000,
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      }
    },
    {
      "id": "write-receipt",
      "name": "Write receipt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        280,
        1320
      ],
      "parameters": {
        "jsCode": "const r=$('Guard current source').first().json; return [{json:{state:'written',contactId:r.contactId,revision:r.revision,operationId:r.operationId,requestId:r.requestId}}];"
      }
    },
    {
      "id": "review-without-purchase",
      "name": "Review without purchase",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2100,
        440
      ],
      "parameters": {
        "jsCode": "return [{json:{state:'review',reason:$json.reason||$json.error?.message||'invalid_or_ambiguous_phone',contactId:$('Configuration').first().json.contactId,sourceRevision:$('Source identity').first().json.revision}}];"
      }
    },
    {
      "id": "retain-operation-for-review",
      "name": "Retain operation for review",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2100,
        880
      ],
      "parameters": {
        "jsCode": "return [{json:{state:'review',reason:$json.reason||'result_pending_or_expired',operationId:$('Prepare saved operation').first().json.id,contactId:$('Source identity').first().json.contactId,sourceRevision:$('Source identity').first().json.revision}}];"
      }
    },
    {
      "id": "setup-and-safe-defaults",
      "name": "Setup and safe defaults",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -1100,
        0
      ],
      "parameters": {
        "content": "## Enrich one HubSpot contact, with recoverable writes\n1. Install n8n-nodes-quietpass. Use version 0.1.2 in self-hosted n8n. It is approved as a verified node.\n2. Select your QuietPass API credential in its node and HTTP steps. Select a HubSpot Service Key credential with contact read/write access in all CRM HTTP steps. Keep credentials out of Configuration.\n3. Create the 15 qp_phone_* text properties in group quietpass_phone (see guide). Set the two Configuration IDs to your portal and an authorized contact.\n4. Manual-only, paid use OFF, ceiling 0. For a free test select only basic_line_type and enable zero-limit saved workflows in QuietPass. For paid use set explicit ceilings and credit consent in QuietPass, then enable allowPaid and a reviewed ceiling here.\n5. Replace the manual input with a trusted contact-change event for production. One contact per execution; preserve the real phone-history revision. Do not use random IDs or execution time. No historical backfill.\n\nGuide: https://quietpass.com/integrations/n8n/",
        "width": 960,
        "height": 600,
        "color": 7
      }
    },
    {
      "id": "recovery-instructions",
      "name": "Recovery instructions",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -1100,
        700
      ],
      "parameters": {
        "content": "## A failed write must not buy another lookup\nThe original operation and quote are saved by QuietPass before execution. On error, keep the failed n8n execution. Copy its operation ID, contact ID, and original phone-history revision into the separate read-only recovery template.\n\nDo not restart a raw stale PATCH or manufacture a new revision. A changed phone or revision prevents the old result from being written. False remains false; unknown clears old QuietPass fields. Pending/expired is not a negative answer.\n\nThe final read and PATCH are separate requests, leaving a small edit window. Stored number, revision receipt, and checked time show what was checked. n8n executions contain contact data: restrict access and set retention.",
        "width": 1000,
        "height": 600,
        "color": 7
      }
    }
  ],
  "connections": {
    "Start manually": {
      "main": [
        [
          {
            "node": "Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configuration": {
      "main": [
        [
          {
            "node": "Validate configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate configuration": {
      "main": [
        [
          {
            "node": "Read HubSpot account",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read HubSpot account": {
      "main": [
        [
          {
            "node": "Verify HubSpot account",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verify HubSpot account": {
      "main": [
        [
          {
            "node": "Read source contact",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read source contact": {
      "main": [
        [
          {
            "node": "Source identity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Source identity": {
      "main": [
        [
          {
            "node": "Has phone history",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has phone history": {
      "main": [
        [
          {
            "node": "Format source phone",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Review without purchase",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format source phone": {
      "main": [
        [
          {
            "node": "Valid source phone",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Valid source phone": {
      "main": [
        [
          {
            "node": "Read workspace limits",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Review without purchase",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read workspace limits": {
      "main": [
        [
          {
            "node": "Spending permission",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Spending permission": {
      "main": [
        [
          {
            "node": "Purchases allowed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Purchases allowed": {
      "main": [
        [
          {
            "node": "Prepare saved operation",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Review without purchase",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare saved operation": {
      "main": [
        [
          {
            "node": "Run original operation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run original operation": {
      "main": [
        [
          {
            "node": "Read retained result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read retained result": {
      "main": [
        [
          {
            "node": "Result is settled",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Result is settled": {
      "main": [
        [
          {
            "node": "Read current contact",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Retain operation for review",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read current contact": {
      "main": [
        [
          {
            "node": "Format current phone",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format current phone": {
      "main": [
        [
          {
            "node": "Guard current source",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Guard current source": {
      "main": [
        [
          {
            "node": "Safe to write",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Safe to write": {
      "main": [
        [
          {
            "node": "Write QuietPass fields",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Retain operation for review",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Write QuietPass fields": {
      "main": [
        [
          {
            "node": "Write receipt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "saveDataErrorExecution": "all",
    "saveDataSuccessExecution": "none",
    "saveManualExecutions": true,
    "executionTimeout": 120
  },
  "pinData": {},
  "tags": []
}
