Deployment source

Identify what initiated each deployment — a Git push, the CLI, the dashboard, the API, or the platform itself.

Every deployment records a deploy_source: what initiated it. Use it to tell an automated Git push apart from a manual CLI deploy, or to filter a project's deployment history by origin.

deploy_source is returned on Function and Frontend deployments and on the project deployment feed.

Values

ValueMeaning
gitA Git push to the connected repository's production branch (auto-deploy).
cliA deploy from the Volcano CLI.
webA deploy from the dashboard.
apiA deploy from a direct API call with a platform token.
systemPlatform-initiated work with no user actor, such as region convergence or a project-delete cascade.
unknownOrigin not recorded — historical deployments created before this field existed.

A deployment correlated to a Git deployment run is always git, regardless of how the request reached the API.

Reading the deployment feed

The project deployment feed returns deploy_source on each attempt:

curl -H "Authorization: Bearer $VOLCANO_TOKEN" \
  "https://api.volcano.dev/projects/$PROJECT_ID/deployments?limit=20"
{
  "data": [
    {
      "id": "d1f8…",
      "resource": { "type": "function", "id": "fn_…", "name": "api", "kind": "standard" },
      "operation": "deploy",
      "status": "active",
      "deploy_source": "git",
      "created_at": "2026-08-06T17:04:11Z"
    }
  ],
  "total": 1,
  "limit": 20,
  "has_more": false
}

The feed lists functions and frontends together. Standard and durable functions both appear as "type": "function", and resource.kind tells them apart. Narrow the feed with resource_type=function or resource_type=frontend, and with function_kind=standard or function_kind=durable:

curl -H "Authorization: Bearer $VOLCANO_TOKEN" \
  "https://api.volcano.dev/projects/$PROJECT_ID/deployments?function_kind=durable&limit=20"

function_kind implies function deployments, so frontends drop out. Combining it with resource_type=frontend answers 400.

Commit

A deploy client can report the commit its upload came from. Volcano records it on the deployment as commit, separate from deploy_source. Send it as a JSON-encoded commit field on a function, durable function, or frontend upload, or as commit on each entry of a batch upload's functions manifest:

curl -X POST "https://api.volcano.dev/projects/$PROJECT_ID/frontends" \
  -H "Authorization: Bearer $VOLCANO_TOKEN" \
  -F name=web \
  -F archive=@web.tar.gz \
  -F 'commit={"repository":"acme/app","sha":"4f1c2b7d9e0a8b3c6d5e4f3a2b1c0d9e8f7a6b5c","dirty":false,"root":"apps/web"}'
FieldValue
repositoryowner/name, or a github.com remote URL such as https://github.com/acme/app.git or git@github.com:acme/app.git. Stored as owner/name, without credentials. An SSH host alias such as github.com-work isn't recognized; send owner/name instead.
shaThe full 40-character commit ID.
dirtytrue when the uploaded files differ from the commit.
rootThe uploaded directory's path from the repository root, such as apps/web, or "" for the repository root. Optional.

repository, sha, and dirty are required. Fields Volcano doesn't know are ignored. An empty commit field, null, or "" reports no commit. A malformed commit, or a repository not on GitHub, answers 400 and deploys nothing.

Volcano then checks the commit through the project's GitHub connection and records what it confirmed as verification:

verificationWhat Volcano confirmed
filesThe commit is the connected repository's, on its production branch, and every uploaded file is the commit's. Only a frontend upload is checked this far.
repositoryThe commit is the connected repository's and on its production branch. A function or durable function upload holds build output, not the repository's layout, so its files aren't compared. Only a function commit reported with dirty: false is checked.
noneNothing.

verified is true only for files. A repository commit says which commit on the production branch the deploy client built from, not that the deployed code is that commit's: anyone who can deploy to the project can report any commit on that branch, an older one included. LavaFlow reads the repository at a function deployment's repository commit, never the uploaded files, and only while the project's repository link is unchanged since Volcano checked the commit. Relinking, reinstalling the GitHub App, renaming the repository, or changing the production branch or root directory ends it; see Code LavaFlow reads.

A frontend's commit is files when:

  • repository is the project's connected repository, matched by repository ID so a rename still matches;
  • sha is on its production branch;
  • every uploaded file is the commit's file at root plus its path in the archive, with the same owner execute bit. A file matches byte for byte, after Git's CRLF-to-LF conversion, or as its Git LFS pointer where the commit's .gitattributes files apply filter=lfs to its path;
  • the upload holds every file the commit has under root, except ones deploy clients leave out: a path with a segment named .git, .gitignore, node_modules, .next, dist, build, .vscode, .idea, .DS_Store, __pycache__, .pytest_cache, .mypy_cache, .ruff_cache, .bundle, .env.local, or volcano.env, or matching .env*.local, *.log, *.pyc, *.pyo, *.rbc, *.swp, or *.swo, and volcano/*.env at root.

root must be the project's root directory, a directory inside it, or one of its parents. An upload from a parent must name an app inside the project's root directory by its path from root: in app_root, or else on the first line of a .volcano/frontend-app-path file at the archive root, which the CLI writes when it uploads a monorepo app from the workspace root. An uploaded file in the project's root directory that the commit doesn't hold sets dirty: true, even when another file can't be checked. A file under a symlink or submodule, a file whose owner execute bit doesn't match the commit's file mode, a file outside the project's root directory that the commit doesn't hold, or one whose match depends on an attribute or attribute pattern Volcano doesn't read leaves the commit unverified without setting dirty.

A commit Volcano can't verify is still recorded, with verification: none, and the deploy goes ahead. That covers a commit from another branch or repository, an upload without root, a root or archive path longer than 4,096 bytes or 128 directories deep, an upload with no file to compare, an upload that leaves out another file, symlink, or submodule the commit holds under root, an upload from a parent without a package.json at its archive root whose only top-level directory, counting dot-directories, has one, a project with no connection, an archive whose global header sets anything but a comment, an archive entry behind more than one extended header, an extended or long-name header with anything but NULs after its data, a directory entry with a . or .. segment, a directory entry the commit holds no file under, a sparse or pre-POSIX archive entry, a tar header with a number that isn't plain octal digits or with a name prefix outside a POSIX ustar header, and a check GitHub doesn't answer in time. Volcano doesn't check a commit reported with dirty: true; it's recorded with verification: none.

A function or durable function commit is repository when repository is the project's connected repository, matched by repository ID, sha is on its production branch, and the commit is reported with dirty: false. Any other function commit, and one Volcano can't check in time, is none.

Function and frontend deployment listings, the project deployment feed, and GET /deployments return the commit. A deployment whose client reported none has no commit:

curl -H "Authorization: Bearer $VOLCANO_TOKEN" \
  "https://api.volcano.dev/projects/$PROJECT_ID/frontends/$FRONTEND_ID/deployments"
{
  "data": [
    {
      "id": "7c2e…",
      "status": "active",
      "deploy_source": "cli",
      "commit": {
        "repository": "acme/app",
        "sha": "4f1c2b7d9e0a8b3c6d5e4f3a2b1c0d9e8f7a6b5c",
        "dirty": false,
        "verified": true,
        "verification": "files"
      }
    }
  ]
}

A frontend deployed from another frontend's build carries the commit of the deployment it publishes. A redeploy reports no commit; it serves the code of the deployment that built its artifact.

Attribution

Request-initiated deployments (cli, web, api) also record initiated_by, the platform user that triggered them. git and system deployments have no user actor, so initiated_by is absent.

Declaring the dashboard client

Authentication is authoritative for the cli classification. A non-CLI client that is the dashboard should send the X-Volcano-Client: web request header so its deployments are recorded as web rather than api.

On this page