{
  "name": "Gary Club — Google Sheets → Sync Contacts",
  "nodes": [
    {
      "parameters": {
        "content": "## ⚡ After import — 3 steps\n\n**1. Set your Google Sheets credential**\nClick **Read Sheet** → set a Google Sheets OAuth2 credential. Make sure the sheet is shared with the service account or OAuth user.\n\n**2. Set your Gary Club credential**\nClick **Upsert Contact** → set **Credential for Header Auth** to your Gary Club Agency key.\n\n**3. Configure the sheet**\nIn the **Read Sheet** node, set:\n- **Spreadsheet ID** — the ID from your sheet's URL.\n- **Sheet** — the sheet/tab name (default: `Sheet1`).\nThe workflow expects columns: `email`, `first_name`, `last_name`, `phone`. Rename them in the **Map Fields** node if your headers differ.\n\n📋 **Notes**\n- The contact upsert is **idempotent on email + phone** — re-runs update existing contacts, never duplicate.\n- The workflow reads ALL rows each run — add a **Filter** node to skip rows already synced (e.g. check for a `synced_at` column).\n- For ongoing sync, set a **Schedule Trigger** (e.g. every hour) instead of Manual Trigger.\n- `source` is set to `google_sheets` for CRM attribution.\n\n📚 Docs: https://docs.gary.club/api/contacts",
        "height": 420,
        "width": 400,
        "color": 5
      },
      "id": "bb000000-0000-4000-8000-000000000000",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [-220, 60]
    },
    {
      "parameters": {},
      "id": "bb000000-0001-4000-8000-000000000001",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [260, 300]
    },
    {
      "parameters": {
        "authentication": "serviceAccount",
        "resource": "spreadsheet",
        "operation": "read",
        "documentId": { "__rl": true, "value": "YOUR_SPREADSHEET_ID", "mode": "id" },
        "sheetName": { "__rl": true, "value": "Sheet1", "mode": "name" },
        "filtersUI": {},
        "options": { "firstRowIsHeader": true }
      },
      "id": "bb000000-0002-4000-8000-000000000002",
      "name": "Read Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [500, 300]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            { "id": "f1", "name": "email", "value": "={{ $json.email }}", "type": "string" },
            { "id": "f2", "name": "first_name", "value": "={{ $json.first_name }}", "type": "string" },
            { "id": "f3", "name": "last_name", "value": "={{ $json.last_name }}", "type": "string" },
            { "id": "f4", "name": "phone", "value": "={{ $json.phone }}", "type": "string" }
          ]
        },
        "options": {}
      },
      "id": "bb000000-0003-4000-8000-000000000003",
      "name": "Map Fields",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [740, 300]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://agency.gary.club/api/public/v1/crm/contacts",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            { "name": "email", "value": "={{ $json.email }}" },
            { "name": "first_name", "value": "={{ $json.first_name }}" },
            { "name": "last_name", "value": "={{ $json.last_name }}" },
            { "name": "phone", "value": "={{ $json.phone }}" },
            { "name": "source", "value": "google_sheets" }
          ]
        },
        "options": {}
      },
      "id": "bb000000-0004-4000-8000-000000000004",
      "name": "Upsert Contact",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [980, 300]
    }
  ],
  "connections": {
    "Manual Trigger": { "main": [[{ "node": "Read Sheet", "type": "main", "index": 0 }]] },
    "Read Sheet": { "main": [[{ "node": "Map Fields", "type": "main", "index": 0 }]] },
    "Map Fields": { "main": [[{ "node": "Upsert Contact", "type": "main", "index": 0 }]] }
  },
  "active": false,
  "settings": { "executionOrder": "v1" },
  "tags": [{ "name": "gary-club-api" }]
}
