---
title: Builds
description: A Build turns one commit into an image, an SBOM and signed provenance; it is immutable once created and ends with digests or a typed failure.
type: tutorial
product: builds
summary: What a build turns one commit into, and what it leaves behind.
updated: 2026-10-01
order: 0
---

<Callout tone="note" title="Today this runs on the management API">
Builds are started by a deploy and read with `GET /v1/builds` and `GET /v1/deployments/builds/{id}` on the management API; the [Builds quickstart](/docs/builds/quickstart) shows them. The `builds` collection in the [API reference](/docs/api/builds) is not served at api.sylphx.com.
</Callout>

A Build turns one commit into an image, an SBOM, and signed provenance. It is
immutable once created: it is never edited, only read. A build ends one of two
ways — with the digests of what it produced, or with a typed failure that says
why it produced nothing.

Every Hosting deploy builds through Sylphx Build today: the image a Service
runs comes from a build of an exact commit, and that build is a record you can
read back.

## What you name, and what the build decides

The only required part of a build is its source: a commit, read exactly.

<PropertyTable
	properties={[
		{
			name: 'source',
			type: 'BuildSource',
			description: 'The exact source. Required.',
			required: true,
		},
		{
			name: 'dockerfile',
			type: 'string',
			description: 'A Dockerfile path relative to the root directory; unset lets the zero-config frontend detect the stack.',
		},
		{
			name: 'target',
			type: 'string',
			description: 'The Dockerfile stage to build.',
		},
		{
			name: 'build_class',
			type: 'string',
			description: 'The class, sylphx-<os>-<size>; the default is sylphx-linux-standard.',
		},
		{
			name: 'build_args',
			type: 'map',
			description: 'Build arguments. Secret values bind through Kernel Secrets, never here.',
		},
		{
			name: 'cache',
			type: 'string',
			description: 'The BuildCache to read and write; the project’s default cache by default.',
		},
	]}
/>

The source is three fields of its own, and the first two are required:

<PropertyTable
	properties={[
		{
			name: 'source_link',
			type: 'string',
			description: 'The Hosting SourceLink naming the repository and its Connection. Required.',
			required: true,
		},
		{
			name: 'commit',
			type: 'string',
			description: 'The full commit SHA to build. Required.',
			required: true,
		},
		{
			name: 'root_directory',
			type: 'string',
			description: 'The directory inside the repository to build; the root by default.',
		},
	]}
/>

A Dockerfile is optional. Unset, the zero-config frontend detects the stack,
which is why a repository builds without one and can add one later without
changing the call.

## Names are paths

A build lives in the project whose repository it builds:

<KeyValue
	items={[
		{ key: 'Build', value: 'orgs/{org}/projects/{project}/builds/{build}', mono: true },
		{ key: 'Build id', value: 'bld_<cell><ulid>', mono: true },
		{ key: 'Build cache', value: 'orgs/{org}/projects/{project}/build_caches/{build_cache}', mono: true },
		{ key: 'Cache id', value: 'bch_<cell><ulid>', mono: true },
	]}
/>

An id is never reused. `build:read` covers reading a build and its caches;
everything that changes one needs `build:write`.

<RelatedDocs
	links={[
		{
			href: '/docs/builds/quickstart',
			label: 'Quickstart',
			description: 'Create a build, read it back, and take its digests.',
		},
		{
			href: '/docs/api/builds',
			label: 'The builds collection',
			description: 'Every method, its scope and its examples.',
		},
		{
			href: '/docs/builds/provenance',
			label: 'Provenance',
			description: 'Where the SBOM and the signed provenance are read back.',
		},
		{
			href: '/docs/cli/builds',
			label: 'The CLI commands',
			description: 'The same calls as sylphx build builds.',
		},
	]}
/>
