{
  "name": "Lumeor | AI social media scheduling (Airtable + Slack approval)",
  "nodes": [
    {
      "parameters": {
        "content": "## AI social media scheduling\nYour Airtable content calendar stays the source of truth. When a planner sets a brief to **Ready to Draft**, Claude writes a caption per network, alt text and an optional first comment. Code checks character limits, links and image aspect ratios. Drafts are saved to the row, and **every post waits for a human to approve it in Slack** before anything is sent to your scheduler.\n\n**Airtable fields (table \"Calendar\")**\nStatus (single select: Ready to Draft, Needs Approval, Scheduled, Changes Requested, Approval Expired, Queue Failed), Paused (checkbox), Publish at (date with time), Networks (multiple select: linkedin, instagram, facebook, x), Goal, Key message, Link (url), Asset (attachment), LinkedIn caption, Instagram caption, Facebook caption, X caption, Alt text, First comment (long text), Scheduler post ID (text).\n\n**Setup**\n1. Credentials: Airtable personal access token, Anthropic, Slack, and a Header Auth credential for your scheduler's API.\n2. Replace REPLACE_WITH_AIRTABLE_BASE_ID, REPLACE_WITH_AIRTABLE_TABLE_ID, REPLACE_WITH_APPROVAL_CHANNEL, REPLACE_WITH_ALERTS_CHANNEL and REPLACE_WITH_SCHEDULER_API_URL.\n3. Map the body of \"Queue in scheduler\" to your scheduler's API. Confirm your plan exposes an API for the networks you post to before you build on it.\n4. Put your voice guide in the Claude node's system prompt.\n\nApprovals are handled one post at a time and wait up to 24 hours, then the row is marked Approval Expired.\n\nModel: claude-opus-5-5. For simple, high-volume classification steps, claude-haiku-5-5 is a cheaper option.\n\nTemplate by Lumeor Studio, https://www.lumeor.studio/guides/automate-social-media-scheduling-with-ai/",
        "height": 900,
        "width": 600,
        "color": 7
      },
      "id": "47d13d59-8194-487c-9b08-6d416e7506a1",
      "name": "About this template",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -80,
        -460
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "*/15 * * * *"
            }
          ]
        }
      },
      "id": "0c68a39d-32c3-4ee1-9326-6739142a68f1",
      "name": "Every 15 minutes",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        300
      ]
    },
    {
      "parameters": {
        "resource": "record",
        "operation": "search",
        "base": {
          "__rl": true,
          "value": "REPLACE_WITH_AIRTABLE_BASE_ID",
          "mode": "id"
        },
        "table": {
          "__rl": true,
          "value": "REPLACE_WITH_AIRTABLE_TABLE_ID",
          "mode": "id"
        },
        "filterByFormula": "AND({Status} = 'Ready to Draft', NOT({Paused}))",
        "returnAll": true,
        "options": {}
      },
      "id": "f610e0ff-60e6-48cc-ae88-cb37984ab01b",
      "name": "Find briefs ready to draft",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2.1,
      "position": [
        220,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "anthropicApi",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ model: 'claude-opus-5-5', max_tokens: 3000, system: \"You write social media captions for a brand from a short brief. Write one caption for each network listed in the brief, and nothing for others.\\nNetwork rules:\\n- linkedin: up to 1,300 characters, professional, short paragraphs, include the link if one is given, at most 3 hashtags.\\n- instagram: up to 2,000 characters, conversational, no clickable links (say \\\"link in bio\\\" if a link is given), up to 5 hashtags at the end.\\n- facebook: up to 600 characters, friendly, include the link if one is given, no hashtags.\\n- x: up to 260 characters including the link, at most 1 hashtag.\\nAlt text describes the image for someone who cannot see it, in under 250 characters. Do not invent details about the image beyond the brief.\\nFirst comment is optional; return an empty string if not useful.\\nNever make claims, prices, statistics or promises that are not in the brief.\\n\\nVOICE GUIDE (replace with your own): clear, warm, specific, no hype words.\", output_config: { \"format\": { \"type\": \"json_schema\", \"schema\": { \"type\": \"object\", \"properties\": { \"captions\": { \"type\": \"array\", \"items\": { \"type\": \"object\", \"properties\": { \"network\": { \"type\": \"string\", \"enum\": [ \"linkedin\", \"instagram\", \"facebook\", \"x\" ] }, \"caption\": { \"type\": \"string\" } }, \"required\": [ \"network\", \"caption\" ], \"additionalProperties\": false } }, \"alt_text\": { \"type\": \"string\" }, \"first_comment\": { \"type\": \"string\" } }, \"required\": [ \"captions\", \"alt_text\", \"first_comment\" ], \"additionalProperties\": false } } }, messages: [ { role: 'user', content: 'Brief (JSON):\\n' + JSON.stringify({ networks: $json.Networks || [], publish_at: $json['Publish at'], goal: $json.Goal || '', key_message: $json['Key message'] || '', link: $json.Link || '', image: ($json.Asset && $json.Asset[0]) ? $json.Asset[0].filename : 'none' }) } ] }) }}",
        "options": {
          "timeout": 120000
        }
      },
      "id": "4d558781-2c1e-46ea-8a1b-874802e808c7",
      "name": "Draft captions and alt text",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        440,
        300
      ],
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000,
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "language": "javaScript",
        "jsCode": "// Checks Claude's drafts against each network's rules before a person ever sees them.\nconst LIMITS = { linkedin: 3000, instagram: 2200, facebook: 5000, x: 280 };\n// Allowed image aspect ratios (width / height) per network.\nconst RATIO = { instagram: [0.8, 1.91], linkedin: [0.5, 2.0], facebook: [0.5, 2.0], x: [0.5, 2.0] };\nconst out = [];\nconst items = $input.all();\nfor (let i = 0; i < items.length; i++) {\n  const res = items[i].json;\n  const brief = $('Find briefs ready to draft').itemMatching(i).json;\n  const fail = (reason) => out.push({ json: { error: reason, details: { record_id: brief.id, key_message: String(brief['Key message'] || '').slice(0, 120) } } });\n\n  if (res.stop_reason === 'refusal' || res.stop_reason === 'max_tokens') { fail(`Claude stopped with stop_reason=${res.stop_reason}`); continue; }\n  // Opus 5.5 may return a thinking block first, so find the text block explicitly.\n  const block = (res.content || []).find((b) => b.type === 'text');\n  if (!block) { fail('Claude response had no text block'); continue; }\n  let d;\n  try { d = JSON.parse(block.text); } catch (e) { fail('Claude returned invalid JSON'); continue; }\n\n  const networks = (brief.Networks || []).map((n) => String(n).toLowerCase());\n  const asset = (brief.Asset || [])[0];\n  const problems = [];\n  if (!networks.length) problems.push('Brief has no networks selected');\n  if (!asset) problems.push('Brief is missing an image in Asset');\n  const byNetwork = {};\n  for (const c of d.captions || []) byNetwork[c.network] = String(c.caption || '').trim();\n  for (const n of networks) {\n    const text = byNetwork[n];\n    if (!LIMITS[n]) { problems.push(`Unknown network \"${n}\"`); continue; }\n    if (!text) { problems.push(`No caption for ${n}`); continue; }\n    if (text.length > LIMITS[n]) problems.push(`${n} caption is ${text.length} characters (limit ${LIMITS[n]})`);\n    if (brief.Link && n !== 'instagram' && !text.includes(brief.Link)) problems.push(`${n} caption is missing the link`);\n    if (asset && asset.width && asset.height) {\n      const r = asset.width / asset.height;\n      const [lo, hi] = RATIO[n];\n      if (r < lo || r > hi) problems.push(`Image ratio ${r.toFixed(2)} does not fit ${n} (${lo} to ${hi})`);\n    }\n  }\n  if (!String(d.alt_text || '').trim()) problems.push('Alt text is empty');\n  if (problems.length) { fail(problems.join('; ')); continue; }\n\n  out.push({\n    json: {\n      id: brief.id,\n      linkedin: byNetwork.linkedin || '',\n      instagram: byNetwork.instagram || '',\n      facebook: byNetwork.facebook || '',\n      x: byNetwork.x || '',\n      alt_text: d.alt_text.trim(),\n      first_comment: String(d.first_comment || '').trim(),\n    },\n  });\n}\nreturn out;"
      },
      "id": "f393babe-95c0-441d-9f81-589f091e0a93",
      "name": "Validate drafts",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        660,
        300
      ],
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "resource": "record",
        "operation": "update",
        "base": {
          "__rl": true,
          "value": "REPLACE_WITH_AIRTABLE_BASE_ID",
          "mode": "id"
        },
        "table": {
          "__rl": true,
          "value": "REPLACE_WITH_AIRTABLE_TABLE_ID",
          "mode": "id"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "id": "={{ $json.id }}",
            "Status": "Needs Approval",
            "LinkedIn caption": "={{ $json.linkedin }}",
            "Instagram caption": "={{ $json.instagram }}",
            "Facebook caption": "={{ $json.facebook }}",
            "X caption": "={{ $json.x }}",
            "Alt text": "={{ $json.alt_text }}",
            "First comment": "={{ $json.first_comment }}"
          },
          "matchingColumns": [
            "id"
          ],
          "schema": [
            {
              "id": "id",
              "displayName": "id",
              "required": false,
              "defaultMatch": true,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Status",
              "displayName": "Status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "LinkedIn caption",
              "displayName": "LinkedIn caption",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Instagram caption",
              "displayName": "Instagram caption",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Facebook caption",
              "displayName": "Facebook caption",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "X caption",
              "displayName": "X caption",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Alt text",
              "displayName": "Alt text",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "First comment",
              "displayName": "First comment",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            }
          ]
        },
        "options": {
          "typecast": true
        }
      },
      "id": "22df86f6-73c3-469e-b3e1-a6122ec0fa5e",
      "name": "Save drafts for approval",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2.1,
      "position": [
        880,
        280
      ]
    },
    {
      "parameters": {
        "batchSize": 1,
        "options": {}
      },
      "id": "694c80f9-d30b-46db-87ba-7589ecb81e0b",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        1100,
        280
      ]
    },
    {
      "parameters": {
        "operation": "sendAndWait",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "REPLACE_WITH_APPROVAL_CHANNEL",
          "mode": "name"
        },
        "message": "=:calendar: *Post for approval* ({{ ($json.Networks || []).join(', ') }}) scheduled {{ $json['Publish at'] }}\n\n{{ $json['LinkedIn caption'] ? '*LinkedIn*\\n' + $json['LinkedIn caption'] + '\\n\\n' : '' }}{{ $json['Instagram caption'] ? '*Instagram*\\n' + $json['Instagram caption'] + '\\n\\n' : '' }}{{ $json['Facebook caption'] ? '*Facebook*\\n' + $json['Facebook caption'] + '\\n\\n' : '' }}{{ $json['X caption'] ? '*X*\\n' + $json['X caption'] + '\\n\\n' : '' }}*Alt text:* {{ $json['Alt text'] }}\n*Image:* {{ $json.Asset && $json.Asset[0] ? $json.Asset[0].url : 'none' }}\n\nTo change the copy, choose Request changes and edit the row in Airtable.",
        "responseType": "approval",
        "approvalOptions": {
          "values": {
            "approvalType": "double",
            "approveLabel": "Approve and queue",
            "disapproveLabel": "Request changes"
          }
        },
        "options": {
          "limitWaitTime": {
            "values": {
              "limitType": "afterTimeInterval",
              "resumeAmount": 24,
              "resumeUnit": "hours"
            }
          },
          "appendAttribution": false
        }
      },
      "id": "40a6db59-6529-41db-b167-91bf6b30bd97",
      "name": "Request approval in Slack",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.3,
      "position": [
        1320,
        300
      ],
      "webhookId": "2d92fd44-a99b-453f-9e61-65e1fa147d66"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "b161970b-c421-40df-a45e-7d06e623bb97",
              "leftValue": "={{ !!($json.data && $json.data.approved === true) }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "looseTypeValidation": true,
        "options": {}
      },
      "id": "768c3bab-70d5-4d5c-b322-e35c700497f4",
      "name": "Approved?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1540,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "REPLACE_WITH_SCHEDULER_API_URL",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Idempotency-Key",
              "value": "={{ $('Loop Over Items').first().json.id }}"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ external_id: $('Loop Over Items').first().json.id, scheduled_at: $('Loop Over Items').first().json['Publish at'], posts: ($('Loop Over Items').first().json.Networks || []).map(n => ({ network: n, text: $('Loop Over Items').first().json[{ linkedin: 'LinkedIn caption', instagram: 'Instagram caption', facebook: 'Facebook caption', x: 'X caption' }[n]] })), media: ($('Loop Over Items').first().json.Asset || []).map(a => ({ url: a.url, alt_text: $('Loop Over Items').first().json['Alt text'] })), first_comment: $('Loop Over Items').first().json['First comment'] || '' }) }}",
        "options": {
          "timeout": 30000
        }
      },
      "id": "3239a6d5-a548-45ee-b0af-63b0491fa336",
      "name": "Queue in scheduler",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1760,
        200
      ],
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000,
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "resource": "record",
        "operation": "update",
        "base": {
          "__rl": true,
          "value": "REPLACE_WITH_AIRTABLE_BASE_ID",
          "mode": "id"
        },
        "table": {
          "__rl": true,
          "value": "REPLACE_WITH_AIRTABLE_TABLE_ID",
          "mode": "id"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "id": "={{ $('Loop Over Items').first().json.id }}",
            "Status": "Scheduled",
            "Scheduler post ID": "={{ $json.id || $json.post_id || $json.update_id || \"\" }}"
          },
          "matchingColumns": [
            "id"
          ],
          "schema": [
            {
              "id": "id",
              "displayName": "id",
              "required": false,
              "defaultMatch": true,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Status",
              "displayName": "Status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Scheduler post ID",
              "displayName": "Scheduler post ID",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            }
          ]
        },
        "options": {
          "typecast": true
        }
      },
      "id": "bf67a106-e55c-477d-a126-c359908b9ca2",
      "name": "Mark scheduled",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2.1,
      "position": [
        1980,
        180
      ]
    },
    {
      "parameters": {
        "resource": "record",
        "operation": "update",
        "base": {
          "__rl": true,
          "value": "REPLACE_WITH_AIRTABLE_BASE_ID",
          "mode": "id"
        },
        "table": {
          "__rl": true,
          "value": "REPLACE_WITH_AIRTABLE_TABLE_ID",
          "mode": "id"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "id": "={{ $('Loop Over Items').first().json.id }}",
            "Status": "={{ $json.data && $json.data.approved === false ? 'Changes Requested' : 'Approval Expired' }}"
          },
          "matchingColumns": [
            "id"
          ],
          "schema": [
            {
              "id": "id",
              "displayName": "id",
              "required": false,
              "defaultMatch": true,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Status",
              "displayName": "Status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            }
          ]
        },
        "options": {
          "typecast": true
        }
      },
      "id": "4f552b25-1600-4b54-83c6-e8656accbbce",
      "name": "Mark changes requested",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2.1,
      "position": [
        1760,
        420
      ]
    },
    {
      "parameters": {
        "resource": "record",
        "operation": "update",
        "base": {
          "__rl": true,
          "value": "REPLACE_WITH_AIRTABLE_BASE_ID",
          "mode": "id"
        },
        "table": {
          "__rl": true,
          "value": "REPLACE_WITH_AIRTABLE_TABLE_ID",
          "mode": "id"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "id": "={{ $('Loop Over Items').first().json.id }}",
            "Status": "Queue Failed"
          },
          "matchingColumns": [
            "id"
          ],
          "schema": [
            {
              "id": "id",
              "displayName": "id",
              "required": false,
              "defaultMatch": true,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Status",
              "displayName": "Status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            }
          ]
        },
        "options": {
          "typecast": true
        }
      },
      "id": "557118f3-edf1-41ab-8a0f-65b5491d344b",
      "name": "Mark queue failed",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2.1,
      "position": [
        1980,
        400
      ]
    },
    {
      "parameters": {
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "REPLACE_WITH_ALERTS_CHANNEL",
          "mode": "name"
        },
        "text": "=:warning: *Social scheduling needs attention*\n*Reason:* {{ typeof $json.error === 'string' ? $json.error : (($json.error && $json.error.message) || 'Unknown error') }}\n*Details:* {{ JSON.stringify($json.details || $json.error || {}).slice(0, 600) }}\n*Execution:* {{ $execution.id }}",
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "id": "833845f0-8fdd-4953-b796-f60a86c387ba",
      "name": "Alert: social post needs attention",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.3,
      "position": [
        880,
        560
      ]
    }
  ],
  "connections": {
    "Every 15 minutes": {
      "main": [
        [
          {
            "node": "Find briefs ready to draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find briefs ready to draft": {
      "main": [
        [
          {
            "node": "Draft captions and alt text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Draft captions and alt text": {
      "main": [
        [
          {
            "node": "Validate drafts",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Alert: social post needs attention",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate drafts": {
      "main": [
        [
          {
            "node": "Save drafts for approval",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Alert: social post needs attention",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save drafts for approval": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Request approval in Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Request approval in Slack": {
      "main": [
        [
          {
            "node": "Approved?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Approved?": {
      "main": [
        [
          {
            "node": "Queue in scheduler",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Mark changes requested",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Queue in scheduler": {
      "main": [
        [
          {
            "node": "Mark scheduled",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Alert: social post needs attention",
            "type": "main",
            "index": 0
          },
          {
            "node": "Mark queue failed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark queue failed": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark scheduled": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark changes requested": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {},
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}
