# Start a g1t.page build from a workflow

> From a running g1t Actions job, open a g1t.page build of one of the repository's projects, which the job then builds in its own checkout with g1t-runner deploy (the g1t/deploy action does both).

<div class="g1t-endpoint"><span class="g1t-method" data-method="post">POST</span><code>/repos/{owner}/{name}/deployments/builds</code></div>

Only the job's own token (G1T_TOKEN) may call it, with `deployments: write` (or `pages: write`) in its `permissions:`. project is the project's slug; it may be left out when the repository has one project with Deployments on. The run decides what is built: a run on the project's production branch (a push, a dispatch or a schedule there) builds production, a pull request's run builds that pull request's preview, and a run on another branch builds that branch's preview; a tag's run is refused. sha is the commit built, the run's unless you say. A pull request from a fork or from someone without the Write role, and a run that had to be approved, get no build secrets. The workspace's plan must include Deployments and its spend limit must not be reached; the build's time is the job's Actions time and is not charged again. Returns deploy_id and token (DEPLOY_ID and DEPLOY_TOKEN for `g1t-runner deploy`, the token good for this build alone until it finishes), kind (production or preview), project, branch, number, commit, url (the app's address), trusted, the project's root_dir, build_command and output_dir, build_as (auto, static, workers or docker) and dockerfile (its Dockerfile's path, or null to find `Dockerfile` or `Containerfile`), and build_env and build_secrets (the project's variables and secrets for builds of that kind). The commit's `g1t / deploy` check is pending until the build reports.

Called from a workflow step with the job's own token, `${{ github.token }}`, in a job with `permissions: deployments: write`; the [`g1t/deploy`](/guides/deployments/#deploying-from-a-workflow) action calls it, masks the token and the secrets, and runs `g1t-runner deploy` with them. Any other token is refused. This is a pull request's run, so it builds the pull request's preview; the same workflow on the production branch builds production. See [Deploying from a workflow](/guides/deployments/#deploying-from-a-workflow).

- **Authentication:** Required. Send an [access token](/reference/api/#authentication) as `Authorization: Bearer`.
- **MCP tool:** [`workflow`](/reference/mcp/#workflow) with `action` `start_deployment_build`, and the same inputs
- **Scope:** An access token needs [`deployments:write`](/guides/authentication/#scopes).

## Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `owner` | string | Yes | The workspace that owns the repository. |
| `name` | string | Yes | The repository's name. |

## Body parameters

Send a JSON object. Names are `snake_case`, as in responses; the `camelCase` spelling is accepted too.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `project` | string | No | The project's slug; may be left out when the repository has one project with Deployments on. |
| `sha` | string | No | The commit built, in hex; the run's commit unless you say. |

## Example request

```sh
curl -X POST https://api.g1t.sh/repos/flagon-io/hello/deployments/builds \
  -H "Authorization: Bearer $G1T_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "project": "hello"
  }'
```

## Example response

A successful request answers `200` with:

```json
{
  "deploy_id": "dpl_01kq9c4e6g8j0m2p4r6t8v0x2z",
  "token": "…",
  "kind": "preview",
  "project": "hello",
  "branch": "new-header",
  "number": 42,
  "commit": "9f2c4e6a8b0d1f3e5a7c9b1d3f5e7a9c0b2d4f6e",
  "url": "https://hello-git-new-header-flagonio.g1t.page",
  "trusted": true,
  "root_dir": "",
  "build_command": null,
  "output_dir": null,
  "build_as": "auto",
  "dockerfile": null,
  "build_env": {
    "PUBLIC_API_URL": "https://api.example.com"
  },
  "build_secrets": {
    "SENTRY_AUTH_TOKEN": "…"
  }
}
```

## Errors

A failed request answers with one of these statuses and a body like `{"error": {"code": "not_found", "message": "Repository not found."}}`. See [errors](/reference/api/#errors).

| Status | Code | When |
| --- | --- | --- |
| 401 | `unauthenticated` | A token is required, or the one sent is not valid. |
| 403 | `forbidden` | The token is valid but not allowed to do this, such as a member-only change, or a token without the scope it needs. |
| 404 | `not_found` | It does not exist, or you cannot see it. |
| 409 | `conflict` | The request conflicts with the current state. |
| 422 | `invalid` | The input is not valid. `message` says which field and why. |
