{
  "info": {
    "name": "Pulbot · Recursos y Flows por API / MCP",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "description": "Conectar recursos (Gmail, Calendar, WhatsApp, recursos con API key) y armar flows en Pulbot, por REST o por MCP.\n\nAntes de empezar: en el entorno, `base_url` (sin /api/v1) y `api_key` (Pulbot → Configuración → API keys). `org_id` es opcional: vacío usa tu organización personal.\n\nEjecuta las carpetas en orden: cada petición guarda en variables lo que la siguiente necesita.\n\nGuía completa: docs/integrations/guia-api-recursos.md"
  },
  "auth": {
    "type": "apikey",
    "apikey": [
      {
        "key": "key",
        "value": "X-API-Key",
        "type": "string"
      },
      {
        "key": "value",
        "value": "{{api_key}}",
        "type": "string"
      },
      {
        "key": "in",
        "value": "header",
        "type": "string"
      }
    ]
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// X-Org-Id solo si se configuró org_id en el entorno.",
          "const org = pm.environment.get('org_id') || pm.collectionVariables.get('org_id');",
          "if (org) pm.request.headers.upsert({ key: 'X-Org-Id', value: org });"
        ]
      }
    }
  ],
  "variable": [
    {
      "key": "connect_url_gmail",
      "value": ""
    },
    {
      "key": "connect_url_calendar",
      "value": ""
    },
    {
      "key": "connect_url_whatsapp",
      "value": ""
    },
    {
      "key": "link_token",
      "value": ""
    },
    {
      "key": "connector_id",
      "value": ""
    },
    {
      "key": "tool_trigger_id",
      "value": ""
    },
    {
      "key": "tool_action_id",
      "value": ""
    },
    {
      "key": "flow_id",
      "value": ""
    },
    {
      "key": "state_trigger_id",
      "value": ""
    },
    {
      "key": "state_action_id",
      "value": ""
    }
  ],
  "item": [
    {
      "name": "1 · Conectar recursos (enlace para tu cliente)",
      "description": "Pides un enlace, se lo entregas a tu cliente, él pulsa «Conectar con Google» y autoriza. El recurso queda en TU cuenta Pulbot. El enlace vence a los 600 s y sirve una sola vez.",
      "item": [
        {
          "name": "Crear enlace · Gmail (Google Workspace)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/api/v1/connection-links/",
            "description": "Devuelve `data.connect_url`. Ábrelo o envíalo a tu cliente: verá la pantalla «Conectar Google Workspace».",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"provider\": \"google\",\n  \"connector_name\": \"Gmail de mi cliente\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"201: enlace creado\", () => pm.response.to.have.status(201));",
                  "const d = pm.response.json().data;",
                  "pm.test(\"connect_url apunta a /connect/ del front\", () => pm.expect(d.connect_url).to.match(/\\/connect\\/[^/]+$/));",
                  "pm.collectionVariables.set(\"connect_url_gmail\", d.connect_url);",
                  "pm.collectionVariables.set(\"link_token\", d.connect_url.split(\"/connect/\")[1]);",
                  "console.log(\"ENTREGA ESTE ENLACE AL CLIENTE →\", d.connect_url);"
                ]
              }
            }
          ]
        },
        {
          "name": "Botón propio · URL de Google (sin pantalla de Pulbot)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/api/v1/connection-links/authorize/",
            "description": "Para tu propio front: tu servidor llama esto cuando el usuario pulsa TU botón y redirige al navegador a data.authorize_url. Al terminar en Google, Pulbot lo devuelve a return_url con ?oauth=success&connector_id=… o ?oauth=cancelled. return_url: https (http solo localhost). external_ref = TU id de este cliente: vuelve en el return_url y reconectar el mismo id actualiza su recurso (no duplica).",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"provider\": \"google\",\n  \"connector_name\": \"Gmail de mi cliente\",\n  \"return_url\": \"{{return_url}}\",\n  \"external_ref\": \"{{external_ref}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"201: URL de Google\", () => pm.response.to.have.status(201));",
                  "const d = pm.response.json().data;",
                  "pm.test(\"Va directo a Google\", () => pm.expect(d.authorize_url).to.match(/^https:\\/\\/accounts\\.google\\.com\\//));",
                  "console.log(\"Redirige a tu usuario a →\", d.authorize_url);"
                ]
              }
            }
          ]
        },
        {
          "name": "Botón propio · URL de WhatsApp (sin pantalla de Pulbot)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/api/v1/connection-links/authorize/",
            "description": "Igual que Google, pero abre Meta (Embedded Signup). Tu servidor llama esto cuando el usuario pulsa TU botón «Conectar WhatsApp» y redirige al navegador a data.authorize_url. Al terminar, Pulbot lo devuelve a return_url con ?oauth=success&connector_id=…, ?oauth=cancelled u ?oauth=error&reason=…. Un solo intento por URL. external_ref = TU id de este cliente.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"provider\": \"whatsapp\",\n  \"connector_name\": \"WhatsApp de mi cliente\",\n  \"return_url\": \"{{return_url}}\",\n  \"external_ref\": \"{{external_ref}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"201 o 400 si WhatsApp no está configurado en este entorno\", () => pm.expect([201, 400]).to.include(pm.response.code));",
                  "if (pm.response.code === 201) {",
                  "  const d = pm.response.json().data;",
                  "  pm.test(\"Va directo a Meta\", () => pm.expect(d.authorize_url).to.match(/^https:\\/\\/www\\.facebook\\.com\\/v[0-9.]+\\/dialog\\/oauth\\?/));",
                  "  console.log(\"Redirige a tu usuario a →\", d.authorize_url);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Crear enlace · Google Calendar",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/api/v1/connection-links/",
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"provider\": \"google-calendar\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"201: enlace creado\", () => pm.response.to.have.status(201));",
                  "const d = pm.response.json().data;",
                  "pm.test(\"connect_url apunta a /connect/ del front\", () => pm.expect(d.connect_url).to.match(/\\/connect\\/[^/]+$/));",
                  "pm.collectionVariables.set(\"connect_url_calendar\", d.connect_url);",
                  "pm.collectionVariables.set(\"link_token\", d.connect_url.split(\"/connect/\")[1]);",
                  "console.log(\"ENTREGA ESTE ENLACE AL CLIENTE →\", d.connect_url);"
                ]
              }
            }
          ]
        },
        {
          "name": "Crear enlace · WhatsApp Business",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/api/v1/connection-links/",
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"provider\": \"whatsapp\",\n  \"connector_name\": \"WhatsApp de mi cliente\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"201 o 400 si WhatsApp no está configurado en este entorno\", () => pm.expect([201, 400]).to.include(pm.response.code));",
                  "if (pm.response.code === 201) pm.collectionVariables.set(\"connect_url_whatsapp\", pm.response.json().data.connect_url);"
                ]
              }
            }
          ]
        },
        {
          "name": "Ver qué verá el cliente (público, sin API key)",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/api/v1/connection-links/{{link_token}}/",
            "description": "Lo que consume la pantalla /connect/<token>. 410 = vencido o ya usado; 404 = token inválido.",
            "auth": {
              "type": "noauth"
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200: enlace vigente\", () => pm.response.to.have.status(200));",
                  "pm.test(\"No expone dueño ni organización\", () => pm.expect(JSON.stringify(pm.response.json().data)).to.not.match(/organization_id|user_id/));"
                ]
              }
            }
          ]
        },
        {
          "name": "Listar mis recursos",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/api/v1/resource-connectors/?page=1&count=20",
            "description": "Después de que tu cliente autorice, aquí aparece el recurso nuevo (nombre = su correo si no diste connector_name)."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200\", () => pm.response.to.have.status(200));",
                  "const list = pm.response.json().data || [];",
                  "if (list.length) pm.collectionVariables.set(\"connector_id\", list[0].id);"
                ]
              }
            }
          ]
        },
        {
          "name": "Recursos de un cliente (external_ref)",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/api/v1/resource-connectors/?external_ref={{external_ref}}&count=50",
            "description": "Solo los recursos de ese cliente final de tu cuenta. Otra cuenta Pulbot nunca los ve."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200\", () => pm.response.to.have.status(200));",
                  "const rows = (pm.response.json().data || []).filter(r => !r.is_platform);",
                  "pm.test(\"todos son de ese cliente\", () => rows.forEach(r => pm.expect(r.external_ref).to.eql(pm.environment.get(\"external_ref\"))));"
                ]
              }
            }
          ]
        },
        {
          "name": "Ver un recurso",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/api/v1/resource-connectors/{{connector_id}}/",
            "description": "Las credenciales salen enmascaradas."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 (o 404 si aún no hay recursos)\", () => pm.expect([200, 404]).to.include(pm.response.code));"
                ]
              }
            }
          ]
        },
        {
          "name": "Catálogo: plataformas conectables",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/api/v1/core/platforms/?connectable=true&count=100",
            "description": "Para recursos con API key (OpenAI, etc.): toma aquí el `id` de la plataforma."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200\", () => pm.response.to.have.status(200));"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "2 · Armar un flow (REST)",
      "description": "Webhook → Gmail «Enviar mensaje». Mismo resultado que en el editor visual.",
      "item": [
        {
          "name": "Buscar herramienta disparador (Webhook Genérico)",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/api/v1/tools/?search=Webhook%20Gen%C3%A9rico&category=all&count=5",
            "description": "`category=all` incluye las herramientas globales de Pulbot (sin él solo ves las tuyas)."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200\", () => pm.response.to.have.status(200));",
                  "const t = (pm.response.json().data || [])[0];",
                  "pm.test(\"Hay herramienta\", () => pm.expect(t).to.be.ok);",
                  "pm.collectionVariables.set(\"tool_trigger_id\", t.id);"
                ]
              }
            }
          ]
        },
        {
          "name": "Buscar herramienta acción (Gmail - Enviar mensaje)",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/api/v1/tools/?search=Gmail%20-%20Enviar&category=all&count=5",
            "description": ""
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const t = (pm.response.json().data || [])[0];",
                  "pm.test(\"Hay herramienta\", () => pm.expect(t).to.be.ok);",
                  "pm.collectionVariables.set(\"tool_action_id\", t.id);"
                ]
              }
            }
          ]
        },
        {
          "name": "Crear flow",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/api/v1/flows/",
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Flow creado por API\",\n  \"description\": \"Webhook → Gmail\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"201\", () => pm.response.to.have.status(201));",
                  "pm.collectionVariables.set(\"flow_id\", pm.response.json().data.id);"
                ]
              }
            }
          ]
        },
        {
          "name": "Agregar nodos",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/api/v1/flows/{{flow_id}}/",
            "description": "`id` tmp-* es provisional: el backend asigna ids reales. Siempre manda `style.position`.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"states\": [\n    {\n      \"id\": \"tmp-trigger\",\n      \"action_tool\": \"{{tool_trigger_id}}\",\n      \"content\": \"Entrada\",\n      \"style\": {\n        \"position\": {\n          \"x\": 0,\n          \"y\": 0\n        }\n      }\n    },\n    {\n      \"id\": \"tmp-action\",\n      \"action_tool\": \"{{tool_action_id}}\",\n      \"content\": \"Enviar correo\",\n      \"style\": {\n        \"position\": {\n          \"x\": 320,\n          \"y\": 0\n        }\n      }\n    }\n  ],\n  \"transitions\": []\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200\", () => pm.response.to.have.status(200));"
                ]
              }
            }
          ]
        },
        {
          "name": "Leer ids reales de los nodos",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/api/v1/flows/{{flow_id}}/",
            "description": ""
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const s = pm.response.json().data.states;",
                  "pm.test(\"2 nodos\", () => pm.expect(s.length).to.eql(2));",
                  "const byTool = id => s.find(x => (x.action_tool?.id || x.action_tool) === id).id;",
                  "pm.collectionVariables.set(\"state_trigger_id\", byTool(pm.collectionVariables.get(\"tool_trigger_id\")));",
                  "pm.collectionVariables.set(\"state_action_id\", byTool(pm.collectionVariables.get(\"tool_action_id\")));"
                ]
              }
            }
          ]
        },
        {
          "name": "Conectar nodos",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/api/v1/flows/{{flow_id}}/",
            "description": "Manda SOLO `transitions`: si incluyes `states`, los nodos se recrean y cambian de id.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"transitions\": [\n    {\n      \"before_state\": \"{{state_trigger_id}}\",\n      \"next_state\": \"{{state_action_id}}\",\n      \"style\": {\n        \"sourceHandle\": \"{{state_trigger_id}}-output\",\n        \"targetHandle\": \"{{state_action_id}}-input\"\n      }\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200\", () => pm.response.to.have.status(200));"
                ]
              }
            }
          ]
        },
        {
          "name": "Ver flow terminado",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/api/v1/flows/{{flow_id}}/",
            "description": "Para que el nodo Gmail envíe de verdad, configúrale el recurso (`resource_connector`) y sus entradas; con MCP lo hace `configure_node`."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const d = pm.response.json().data;",
                  "pm.test(\"2 nodos y 1 conexión\", () => { pm.expect(d.states.length).to.eql(2); pm.expect(d.transitions.length).to.eql(1); });"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "3 · Lo mismo por MCP",
      "description": "Servidor MCP alojado en {{base_url}}/mcp/ (Streamable HTTP, header X-API-Key). Es lo que usa un agente (Claude, Cursor…). Estas peticiones muestran el JSON-RPC por debajo.",
      "item": [
        {
          "name": "MCP · initialize",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json, text/event-stream"
              }
            ],
            "url": "{{base_url}}/mcp/",
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"jsonrpc\": \"2.0\",\n  \"id\": 1,\n  \"method\": \"initialize\",\n  \"params\": {\n    \"protocolVersion\": \"2025-06-18\",\n    \"capabilities\": {},\n    \"clientInfo\": {\n      \"name\": \"postman\",\n      \"version\": \"1\"\n    }\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"servidor pulbot\", () => pm.expect(pm.response.json().result.serverInfo.name).to.eql(\"pulbot\"));"
                ]
              }
            }
          ]
        },
        {
          "name": "MCP · listar herramientas",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json, text/event-stream"
              }
            ],
            "url": "{{base_url}}/mcp/",
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"jsonrpc\": \"2.0\",\n  \"id\": 2,\n  \"method\": \"tools/list\",\n  \"params\": {}\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const names = pm.response.json().result.tools.map(t => t.name);",
                  "pm.test(\"incluye create_connection_link y create_flow\", () => { pm.expect(names).to.include(\"create_connection_link\"); pm.expect(names).to.include(\"create_flow\"); });"
                ]
              }
            }
          ]
        },
        {
          "name": "MCP · crear enlace de conexión Gmail",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json, text/event-stream"
              }
            ],
            "url": "{{base_url}}/mcp/",
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"jsonrpc\": \"2.0\",\n  \"id\": 3,\n  \"method\": \"tools/call\",\n  \"params\": {\n    \"name\": \"create_connection_link\",\n    \"arguments\": {\n      \"provider\": \"google\",\n      \"connector_name\": \"Gmail vía MCP\"\n    }\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const r = pm.response.json().result;",
                  "pm.test(\"sin error\", () => pm.expect(r.isError).to.eql(false));",
                  "const d = JSON.parse(r.content[0].text);",
                  "pm.test(\"connect_url\", () => pm.expect(d.connect_url).to.match(/\\/connect\\//));",
                  "console.log(\"Enlace vía MCP →\", d.connect_url);"
                ]
              }
            }
          ]
        },
        {
          "name": "MCP · crear flow",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json, text/event-stream"
              }
            ],
            "url": "{{base_url}}/mcp/",
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"jsonrpc\": \"2.0\",\n  \"id\": 4,\n  \"method\": \"tools/call\",\n  \"params\": {\n    \"name\": \"create_flow\",\n    \"arguments\": {\n      \"name\": \"Flow creado por MCP\"\n    }\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const r = pm.response.json().result;",
                  "pm.test(\"sin error\", () => pm.expect(r.isError).to.eql(false));",
                  "pm.collectionVariables.set(\"mcp_flow_id\", JSON.parse(r.content[0].text).id);"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "4 · Limpieza (opcional)",
      "description": "Borra los flows de prueba creados arriba.",
      "item": [
        {
          "name": "Borrar flow REST",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": "{{base_url}}/api/v1/flows/{{flow_id}}/",
            "description": ""
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"borrado\", () => pm.expect([200, 204]).to.include(pm.response.code));"
                ]
              }
            }
          ]
        },
        {
          "name": "Borrar flow MCP",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": "{{base_url}}/api/v1/flows/{{mcp_flow_id}}/",
            "description": ""
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"borrado\", () => pm.expect([200, 204]).to.include(pm.response.code));"
                ]
              }
            }
          ]
        }
      ]
    }
  ]
}
