When it fires
Inside CreateVersionService, once the variable_versions row is committed and before the service returns. Three surfaces publish versions: the dashboard Publish action, the CLI (envless publish, an alias of envless version publish), and POST /projects/{slug}/environments/{environmentSlug}/versions.
A version captures every non-deleted variable of one environment into variable_version_entries. The event is per environment, so a CLI publish that targets several environments emits one variable_version.created for each of them.
Nothing re-snapshots those entries afterwards, but their stored ciphertext is rewritten in place when the workspace passphrase is rotated (POST /projects/{slug}/environments/{environmentSlug}/versions/entries/reencrypt), so treat a version as a frozen set of variables rather than frozen bytes.
No event is written when the publish is refused. A note longer than 200 characters, or an environment that already holds 1000 versions, fails before the event is emitted.
Payload
{
type: 'variable_version.created',
data: {
version: {
id: string
label: string // 'v' + (existing version count for the environment + 1), e.g. 'v12'
note: string | null // trimmed, null when empty, 200 characters max
variableCount: number // non-deleted variables captured in the snapshot
environmentId: string
createdAt: string // ISO 8601
}
}
}data.version is the entire payload. The envelope around it (id, apiVersion, createdAt, workspaceId, actor) is identical for every event type, see Webhooks Overview.
Example
{
"type": "variable_version.created",
"data": {
"version": {
"id": "0192a1b2-c3d4-7000-8000-000000000050",
"label": "v12",
"note": "Before stripe integration",
"variableCount": 18,
"environmentId": "0192a1b2-c3d4-7000-8000-000000000020",
"createdAt": "2026-05-31T11:30:00.000Z"
}
}
}