{
  "manifest_version": "1.0.0",
  "template": {
    "id": "bb970295-8ba7-4f6d-857f-704779dd590d",
    "slug": "skyvern",
    "name": "Skyvern",
    "description": "AI agents that drive a real browser to fill forms and scrape sites.",
    "url": "https://railway.com/deploy/skyvern",
    "upstream": {
      "image": "caddy:2-alpine"
    }
  },
  "services": [
    {
      "name": "skyvern-ui",
      "source": {
        "image": "public.ecr.aws/skyvern/skyvern-ui:v1.0.51"
      },
      "needs_volume": false,
      "http": false
    },
    {
      "name": "postgres",
      "source": {
        "image": "ghcr.io/railwayapp-templates/postgres-ssl:18"
      },
      "needs_volume": true,
      "volume_mount_path": "/var/lib/postgresql/data",
      "http": false
    },
    {
      "name": "proxy",
      "source": {
        "image": "caddy:2-alpine"
      },
      "needs_volume": false,
      "http": true
    },
    {
      "name": "skyvern",
      "source": {
        "image": "public.ecr.aws/skyvern/skyvern:v1.0.51"
      },
      "needs_volume": true,
      "volume_mount_path": "/data",
      "http": false
    }
  ],
  "required_inputs": [
    {
      "key": "PORT",
      "service": "skyvern-ui",
      "description": "Port localServer.js binds and the healthcheck probes; both are 8080.",
      "secret": false,
      "strategy": "default",
      "default": "8080"
    },
    {
      "key": "VITE_ENVIRONMENT",
      "service": "skyvern-ui",
      "description": "Deployment mode. Leave as local for self-hosting.",
      "secret": false,
      "strategy": "default",
      "default": "local"
    },
    {
      "key": "VITE_API_BASE_URL",
      "service": "skyvern-ui",
      "description": "Browser-facing API origin, routed through the proxy.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "VITE_WSS_BASE_URL",
      "service": "skyvern-ui",
      "description": "Websocket origin for live browser streaming.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "SKYVERN_API_BASE_URL",
      "service": "skyvern-ui",
      "description": "Private API address the dashboard itself calls to mint browser sessions.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "SKYVERN_CREDENTIAL_URL",
      "service": "skyvern-ui",
      "description": "Private URL polled at startup until the API has minted its org key.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "VITE_ENABLE_CODE_BLOCK",
      "service": "skyvern-ui",
      "description": "Must match ENABLE_CODE_BLOCK on the skyvern service.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "VITE_ARTIFACT_API_BASE_URL",
      "service": "skyvern-ui",
      "description": "Bare origin for artifacts; the app appends /artifact/... itself.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "VITE_BROWSER_STREAMING_MODE",
      "service": "skyvern-ui",
      "description": "Must match BROWSER_STREAMING_MODE on the skyvern service.",
      "secret": false,
      "strategy": "default",
      "default": "cdp"
    },
    {
      "key": "PGDATA",
      "service": "postgres",
      "description": "Data directory inside the mounted volume.",
      "secret": false,
      "strategy": "default",
      "default": "/var/lib/postgresql/data/pgdata"
    },
    {
      "key": "PGHOST",
      "service": "postgres",
      "description": "Private hostname other services connect to.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PGPORT",
      "service": "postgres",
      "description": "Postgres port.",
      "secret": false,
      "strategy": "default",
      "default": "5432"
    },
    {
      "key": "PGUSER",
      "service": "postgres",
      "description": "Mirror of the superuser name.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PGDATABASE",
      "service": "postgres",
      "description": "Mirror of the database name.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PGPASSWORD",
      "service": "postgres",
      "description": "Mirror of the superuser password.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "POSTGRES_DB",
      "service": "postgres",
      "description": "Database Skyvern migrates into.",
      "secret": false,
      "strategy": "default",
      "default": "skyvern"
    },
    {
      "key": "DATABASE_URL",
      "service": "postgres",
      "description": "Standard connection string. Skyvern uses DATABASE_STRING instead.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "POSTGRES_USER",
      "service": "postgres",
      "description": "Postgres superuser name.",
      "secret": false,
      "strategy": "default",
      "default": "postgres"
    },
    {
      "key": "POSTGRES_PASSWORD",
      "service": "postgres",
      "description": "Postgres superuser password. Generated per deploy.",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "PORT",
      "service": "proxy",
      "description": "Port Caddy listens on and the public domain targets.",
      "secret": false,
      "strategy": "default",
      "default": "8080"
    },
    {
      "key": "UI_HOST",
      "service": "proxy",
      "description": "Private address backing every other route.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "API_HOST",
      "service": "proxy",
      "description": "Private address backing the /api/* and /v1/* routes.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "CADDYFILE",
      "service": "proxy",
      "description": "Caddy routing config, written to disk at start so it can read the hosts below.",
      "secret": false,
      "strategy": "default",
      "default": "{\n\tadmin off\n\tauto_https off\n}\n\n:{$PORT} {\n\thandle /proxy-healthz {\n\t\trespond 200\n\t}\n\thandle /api/* {\n\t\treverse_proxy {$API_HOST}\n\t}\n\thandle /v1/* {\n\t\treverse_proxy {$API_HOST}\n\t}\n\thandle /artifact/* {\n\t\treverse_proxy {$ARTIFACT_HOST}\n\t}\n\thandle {\n\t\treverse_proxy {$UI_HOST}\n\t}\n}\n"
    },
    {
      "key": "ARTIFACT_HOST",
      "service": "proxy",
      "description": "Private address backing the /artifact/* routes.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "ENV",
      "service": "skyvern",
      "description": "Deployment mode. Leave as local for self-hosting.",
      "secret": false,
      "strategy": "default",
      "default": "local"
    },
    {
      "key": "PORT",
      "service": "skyvern",
      "description": "Port the API binds and the healthcheck probes; the two must match.",
      "secret": false,
      "strategy": "default",
      "default": "8000"
    },
    {
      "key": "LLM_KEY",
      "service": "skyvern",
      "description": "Model Skyvern plans and acts with, for example OPENAI_GPT5_5.",
      "secret": true,
      "strategy": "default",
      "default": "OPENAI_GPT5_5"
    },
    {
      "key": "SECRET_KEY",
      "service": "skyvern",
      "description": "Signs the organization API token. Generated per deploy.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "BROWSER_TYPE",
      "service": "skyvern",
      "description": "Headful Chromium under Xvfb, required for live browser streaming.",
      "secret": false,
      "strategy": "default",
      "default": "chromium-headful"
    },
    {
      "key": "ENABLE_OPENAI",
      "service": "skyvern",
      "description": "Enables the OpenAI provider. Swap for another ENABLE_* to change provider.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "OPENAI_API_KEY",
      "service": "skyvern",
      "description": "Your OpenAI API key. Skyvern cannot run a task without an LLM key.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "DATABASE_STRING",
      "service": "skyvern",
      "description": "Postgres URL using the postgresql+psycopg driver Skyvern requires.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "ENABLE_CODE_BLOCK",
      "service": "skyvern",
      "description": "Enables code blocks in workflows. Must match the dashboard.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "CREDENTIAL_VAULT_TYPE",
      "service": "skyvern",
      "description": "Uses the built-in vault rather than Bitwarden or 1Password.",
      "secret": false,
      "strategy": "default",
      "default": "skyvern"
    },
    {
      "key": "BROWSER_STREAMING_MODE",
      "service": "skyvern",
      "description": "How the live browser is streamed. Must match the dashboard.",
      "secret": false,
      "strategy": "default",
      "default": "cdp"
    },
    {
      "key": "SKYVERN_CREDENTIALS_FILE",
      "service": "skyvern",
      "description": "Organization key file, kept on the volume so it survives redeploys.",
      "secret": false,
      "strategy": "default",
      "default": "/data/.skyvern/credentials.toml"
    },
    {
      "key": "ENABLE_LOCAL_CREDENTIAL_VAULT",
      "service": "skyvern",
      "description": "Stores site credentials on the volume.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    }
  ],
  "deploy": {
    "mcp": {
      "server": "railway",
      "tool": "deploy_template",
      "args": {
        "template_code": "skyvern"
      }
    },
    "cli": "railway deploy --template skyvern",
    "api": {
      "method": "POST",
      "path": "/graphql/v2",
      "body": {
        "query": "mutation templateDeploy($input: TemplateDeployV2Input!) { templateDeployV2(input: $input) { projectId workflowId } }",
        "variables": {
          "input": {
            "templateId": "bb970295-8ba7-4f6d-857f-704779dd590d",
            "serializedConfig": {
              "services": {
                "59b2ab8a-3afe-4796-9ae8-aae7d37b84b6": {
                  "icon": "https://github.com/Skyvern-AI.png?size=460",
                  "name": "skyvern-ui",
                  "deploy": {
                    "startCommand": "sh -c 'cat > /tmp/skyvern-token.mjs <<\"TOKEOF\"\nconst res = await fetch(process.env.SKYVERN_CREDENTIAL_URL);\nif (res.ok) process.stdout.write((await res.text()).trim());\nTOKEOF\nfor i in $(seq 1 60); do\n  KEY=$(node /tmp/skyvern-token.mjs 2>/dev/null || true)\n  if [ -n \"$KEY\" ]; then\n    export SKYVERN_API_KEY=\"$KEY\"\n    echo \"picked up skyvern org API key\"\n    break\n  fi\n  echo \"waiting for the skyvern API to mint its org key...\"\n  sleep 5\ndone\nexec /bin/bash /app/entrypoint-skyvernui.sh'",
                    "healthcheckPath": "/",
                    "healthcheckTimeout": 600
                  },
                  "source": {
                    "image": "public.ecr.aws/skyvern/skyvern-ui:v1.0.51"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "Port localServer.js binds and the healthcheck probes; both are 8080.",
                      "defaultValue": "8080"
                    },
                    "VITE_ENVIRONMENT": {
                      "isOptional": false,
                      "description": "Deployment mode. Leave as local for self-hosting.",
                      "defaultValue": "local"
                    },
                    "VITE_API_BASE_URL": {
                      "isOptional": false,
                      "description": "Browser-facing API origin, routed through the proxy.",
                      "defaultValue": "https://${{proxy.RAILWAY_PUBLIC_DOMAIN}}/api/v1"
                    },
                    "VITE_WSS_BASE_URL": {
                      "isOptional": false,
                      "description": "Websocket origin for live browser streaming.",
                      "defaultValue": "wss://${{proxy.RAILWAY_PUBLIC_DOMAIN}}/api/v1"
                    },
                    "SKYVERN_API_BASE_URL": {
                      "isOptional": false,
                      "description": "Private API address the dashboard itself calls to mint browser sessions.",
                      "defaultValue": "http://${{skyvern.RAILWAY_PRIVATE_DOMAIN}}:8000/api/v1"
                    },
                    "SKYVERN_CREDENTIAL_URL": {
                      "isOptional": false,
                      "description": "Private URL polled at startup until the API has minted its org key.",
                      "defaultValue": "http://${{skyvern.RAILWAY_PRIVATE_DOMAIN}}:9091/"
                    },
                    "VITE_ENABLE_CODE_BLOCK": {
                      "isOptional": false,
                      "description": "Must match ENABLE_CODE_BLOCK on the skyvern service.",
                      "defaultValue": "true"
                    },
                    "VITE_ARTIFACT_API_BASE_URL": {
                      "isOptional": false,
                      "description": "Bare origin for artifacts; the app appends /artifact/... itself.",
                      "defaultValue": "https://${{proxy.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "VITE_BROWSER_STREAMING_MODE": {
                      "isOptional": false,
                      "description": "Must match BROWSER_STREAMING_MODE on the skyvern service.",
                      "defaultValue": "cdp"
                    }
                  }
                },
                "63787f94-4a61-4356-8f30-d323dc279dd0": {
                  "icon": "https://devicons.railway.com/i/postgresql.svg",
                  "name": "postgres",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "image": "ghcr.io/railwayapp-templates/postgres-ssl:18"
                  },
                  "variables": {
                    "PGDATA": {
                      "isOptional": false,
                      "description": "Data directory inside the mounted volume.",
                      "defaultValue": "/var/lib/postgresql/data/pgdata"
                    },
                    "PGHOST": {
                      "isOptional": false,
                      "description": "Private hostname other services connect to.",
                      "defaultValue": "${{RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "PGPORT": {
                      "isOptional": false,
                      "description": "Postgres port.",
                      "defaultValue": "5432"
                    },
                    "PGUSER": {
                      "isOptional": false,
                      "description": "Mirror of the superuser name.",
                      "defaultValue": "${{POSTGRES_USER}}"
                    },
                    "PGDATABASE": {
                      "isOptional": false,
                      "description": "Mirror of the database name.",
                      "defaultValue": "${{POSTGRES_DB}}"
                    },
                    "PGPASSWORD": {
                      "isOptional": false,
                      "description": "Mirror of the superuser password.",
                      "defaultValue": "${{POSTGRES_PASSWORD}}"
                    },
                    "POSTGRES_DB": {
                      "isOptional": false,
                      "description": "Database Skyvern migrates into.",
                      "defaultValue": "skyvern"
                    },
                    "DATABASE_URL": {
                      "isOptional": false,
                      "description": "Standard connection string. Skyvern uses DATABASE_STRING instead.",
                      "defaultValue": "postgresql://${{POSTGRES_USER}}:${{POSTGRES_PASSWORD}}@${{RAILWAY_PRIVATE_DOMAIN}}:5432/${{POSTGRES_DB}}"
                    },
                    "POSTGRES_USER": {
                      "isOptional": false,
                      "description": "Postgres superuser name.",
                      "defaultValue": "postgres"
                    },
                    "POSTGRES_PASSWORD": {
                      "isOptional": false,
                      "description": "Postgres superuser password. Generated per deploy.",
                      "defaultValue": "{{POSTGRES_PASSWORD}}"
                    }
                  },
                  "volumeMounts": {
                    "63787f94-4a61-4356-8f30-d323dc279dd0": {
                      "mountPath": "/var/lib/postgresql/data"
                    }
                  }
                },
                "bdc860d1-6944-4e9a-8552-f10b5218ca3c": {
                  "icon": "https://github.com/caddyserver.png?size=460",
                  "name": "proxy",
                  "deploy": {
                    "startCommand": "sh -c 'printf \"%s\" \"$CADDYFILE\" > /etc/caddy/Caddyfile && exec caddy run --config /etc/caddy/Caddyfile --adapter caddyfile'",
                    "healthcheckPath": "/proxy-healthz",
                    "healthcheckTimeout": 300
                  },
                  "source": {
                    "image": "caddy:2-alpine"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "Port Caddy listens on and the public domain targets.",
                      "defaultValue": "8080"
                    },
                    "UI_HOST": {
                      "isOptional": false,
                      "description": "Private address backing every other route.",
                      "defaultValue": "http://${{skyvern-ui.RAILWAY_PRIVATE_DOMAIN}}:8080"
                    },
                    "API_HOST": {
                      "isOptional": false,
                      "description": "Private address backing the /api/* and /v1/* routes.",
                      "defaultValue": "http://${{skyvern.RAILWAY_PRIVATE_DOMAIN}}:8000"
                    },
                    "CADDYFILE": {
                      "isOptional": false,
                      "description": "Caddy routing config, written to disk at start so it can read the hosts below.",
                      "defaultValue": "{\n\tadmin off\n\tauto_https off\n}\n\n:{$PORT} {\n\thandle /proxy-healthz {\n\t\trespond 200\n\t}\n\thandle /api/* {\n\t\treverse_proxy {$API_HOST}\n\t}\n\thandle /v1/* {\n\t\treverse_proxy {$API_HOST}\n\t}\n\thandle /artifact/* {\n\t\treverse_proxy {$ARTIFACT_HOST}\n\t}\n\thandle {\n\t\treverse_proxy {$UI_HOST}\n\t}\n}\n"
                    },
                    "ARTIFACT_HOST": {
                      "isOptional": false,
                      "description": "Private address backing the /artifact/* routes.",
                      "defaultValue": "http://${{skyvern.RAILWAY_PRIVATE_DOMAIN}}:9090"
                    }
                  },
                  "networking": {
                    "tcpProxies": {},
                    "serviceDomains": {
                      "<hasDomain>": {
                        "port": 8080
                      }
                    }
                  }
                },
                "e733e18b-6fa0-452b-9fa9-b08f005170fd": {
                  "icon": "https://github.com/Skyvern-AI.png?size=460",
                  "name": "skyvern",
                  "deploy": {
                    "startCommand": "sh -c 'cat > /tmp/skyvern-aux.mjs <<\"AUXEOF\"\n\nimport { createServer } from \"node:http\";\nimport { createReadStream, existsSync, readFileSync, statSync } from \"node:fs\";\nimport { extname, resolve } from \"node:path\";\n\n// Exactly the three directories that compose shares with the UI container.\n// Anything wider is a public read primitive: /data also holds the file\n// .skyvern/credentials.toml (the permanent org API key), the local credential\n// vault and saved browser sessions. No apostrophes below this line: the whole\n// script ships as a single-quoted sh -c argument.\nconst ROOTS = [\"/data/artifacts\", \"/data/videos\", \"/data/har\"];\nconst CREDS = process.env.SKYVERN_CREDENTIALS_FILE || \"/data/.skyvern/credentials.toml\";\nconst TYPES = {\n  \".png\": \"image/png\", \".jpg\": \"image/jpeg\", \".jpeg\": \"image/jpeg\",\n  \".webp\": \"image/webp\", \".gif\": \"image/gif\", \".svg\": \"image/svg+xml\",\n};\n\nfunction safePath(raw) {\n  if (!raw) return null;\n  const abs = resolve(raw);\n  return ROOTS.some((root) => abs.startsWith(root + \"/\")) ? abs : null;\n}\n\ncreateServer((req, res) => {\n  let url;\n  try {\n    url = new URL(req.url, \"http://localhost\");\n  } catch {\n    res.writeHead(400);\n    return res.end(\"bad request\");\n  }\n  const path = safePath(url.searchParams.get(\"path\"));\n  if (!path || !existsSync(path)) {\n    res.writeHead(404);\n    return res.end(\"not found\");\n  }\n  if (url.pathname === \"/artifact/recording\") {\n    const size = statSync(path).size;\n    const start = req.headers.range ? Number(req.headers.range.replace(/\\D/g, \"\")) : 0;\n    const end = Math.min(start + 1000000, size - 1);\n    res.writeHead(206, {\n      \"Content-Range\": \"bytes \" + start + \"-\" + end + \"/\" + size,\n      \"Accept-Ranges\": \"bytes\",\n      \"Content-Length\": end - start + 1,\n      \"Content-Type\": \"video/mp4\",\n    });\n    return createReadStream(path, { start, end }).pipe(res);\n  }\n  if (url.pathname === \"/artifact/image\") {\n    res.writeHead(200, { \"Content-Type\": TYPES[extname(path).toLowerCase()] || \"application/octet-stream\" });\n    return createReadStream(path).pipe(res);\n  }\n  if (url.pathname === \"/artifact/json\") {\n    res.writeHead(200, { \"Content-Type\": \"application/json\" });\n    return res.end(readFileSync(path));\n  }\n  if (url.pathname === \"/artifact/text\") {\n    res.writeHead(200, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n    return res.end(readFileSync(path));\n  }\n  res.writeHead(404);\n  res.end(\"not found\");\n}).listen(9090, \"0.0.0.0\");\n\ncreateServer((req, res) => {\n  let token = \"\";\n  try {\n    const found = readFileSync(CREDS, \"utf8\").match(/cred\\s*=\\s*\"([^\"]*)\"/);\n    if (found) token = found[1];\n  } catch {}\n  if (!token) {\n    res.writeHead(503);\n    return res.end(\"\");\n  }\n  res.writeHead(200, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n  res.end(token);\n}).listen(9091, \"0.0.0.0\");\n\nAUXEOF\nnode /tmp/skyvern-aux.mjs &\nexec /bin/bash /app/entrypoint-skyvern.sh'",
                    "healthcheckPath": "/api/v1/heartbeat",
                    "healthcheckTimeout": 900
                  },
                  "source": {
                    "image": "public.ecr.aws/skyvern/skyvern:v1.0.51"
                  },
                  "variables": {
                    "ENV": {
                      "isOptional": false,
                      "description": "Deployment mode. Leave as local for self-hosting.",
                      "defaultValue": "local"
                    },
                    "PORT": {
                      "isOptional": false,
                      "description": "Port the API binds and the healthcheck probes; the two must match.",
                      "defaultValue": "8000"
                    },
                    "LLM_KEY": {
                      "isOptional": false,
                      "description": "Model Skyvern plans and acts with, for example OPENAI_GPT5_5.",
                      "defaultValue": "OPENAI_GPT5_5"
                    },
                    "SECRET_KEY": {
                      "isOptional": false,
                      "description": "Signs the organization API token. Generated per deploy.",
                      "defaultValue": "{{SECRET_KEY}}"
                    },
                    "BROWSER_TYPE": {
                      "isOptional": false,
                      "description": "Headful Chromium under Xvfb, required for live browser streaming.",
                      "defaultValue": "chromium-headful"
                    },
                    "ENABLE_OPENAI": {
                      "isOptional": false,
                      "description": "Enables the OpenAI provider. Swap for another ENABLE_* to change provider.",
                      "defaultValue": "true"
                    },
                    "OPENAI_API_KEY": {
                      "isOptional": false,
                      "description": "Your OpenAI API key. Skyvern cannot run a task without an LLM key.",
                      "defaultValue": "{{OPENAI_API_KEY}}"
                    },
                    "DATABASE_STRING": {
                      "isOptional": false,
                      "description": "Postgres URL using the postgresql+psycopg driver Skyvern requires.",
                      "defaultValue": "postgresql+psycopg://${{postgres.PGUSER}}:${{postgres.POSTGRES_PASSWORD}}@${{postgres.RAILWAY_PRIVATE_DOMAIN}}:5432/${{postgres.PGDATABASE}}"
                    },
                    "ENABLE_CODE_BLOCK": {
                      "isOptional": false,
                      "description": "Enables code blocks in workflows. Must match the dashboard.",
                      "defaultValue": "true"
                    },
                    "CREDENTIAL_VAULT_TYPE": {
                      "isOptional": false,
                      "description": "Uses the built-in vault rather than Bitwarden or 1Password.",
                      "defaultValue": "skyvern"
                    },
                    "BROWSER_STREAMING_MODE": {
                      "isOptional": false,
                      "description": "How the live browser is streamed. Must match the dashboard.",
                      "defaultValue": "cdp"
                    },
                    "SKYVERN_CREDENTIALS_FILE": {
                      "isOptional": false,
                      "description": "Organization key file, kept on the volume so it survives redeploys.",
                      "defaultValue": "/data/.skyvern/credentials.toml"
                    },
                    "ENABLE_LOCAL_CREDENTIAL_VAULT": {
                      "isOptional": false,
                      "description": "Stores site credentials on the volume.",
                      "defaultValue": "true"
                    }
                  },
                  "volumeMounts": {
                    "e733e18b-6fa0-452b-9fa9-b08f005170fd": {
                      "mountPath": "/data"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "post_deploy": {
    "healthcheck": {
      "service": "proxy",
      "method": "GET",
      "path": "/proxy-healthz",
      "expect_status": 200
    }
  },
  "resources": {
    "expected_services": 4,
    "needs_volume": true
  },
  "generated_at": "2026-09-20T16:14:49.616Z",
  "generator_version": "0.1.0",
  "status": "validated",
  "validated_at": "2026-09-19T13:36:56.737Z",
  "success_rate_30d": 1,
  "validation": {
    "last_run_id": "run_71132f74000e43d8be54",
    "checks": [
      {
        "name": "workflow_completed",
        "passed": true
      },
      {
        "name": "all_services_deployed",
        "passed": true
      },
      {
        "name": "healthcheck",
        "passed": true
      },
      {
        "name": "stays_up",
        "passed": true
      }
    ],
    "typical_ready_seconds": 112,
    "typical_build_seconds": 0,
    "typical_start_seconds": 10,
    "slowest_service": "proxy"
  }
}
