Create or update an environment's protection rules
Create an environment's protection rules, or change them; fields left out stay as they are.
/repos/{owner}/{name}/environments/{environment}A job that names the environment with environment: waits, once its needs are done, until the rules let it through, and only then gets the environment’s secrets. reviewers: up to 6, each {“type”: “User” or “Team”, “name”: a username or a team’s slug} (id is read as the name too); a job waits until one of them approves it. prevent_self_review: whoever started the run may not approve it. wait_timer: minutes each job waits, 0 to 43200. deployment_branch_policy: null lets every branch deploy; {“protected_branches”: true} only branches the repository’s rules protect (the default branch included); {“custom_branch_policies”: true} only the branches and tags in branch_policies, each {“name”: a pattern such as release/*, “type”: “branch” or “tag”}. can_admins_bypass (true unless you say): admins may approve without being reviewers, which also skips the wait. The environment’s name is up to 40 letters, digits, - and _, matched without regard to case. Needs the Admin role. Returns the environment with its protection_rules.
Fields left out stay as they are. A job with environment: production now waits for syntaqx or someone in deployers to approve it, then ten minutes, and runs only on a protected branch.
- Authentication: Required. Send an access token as
Authorization: Bearer. - MCP tool:
workflowwithactionupdate_environment, and the same inputs - Scope: An access token needs
repo:admin.
Path parameters
Section titled “Path parameters”| Name | Type | Required | Description |
|---|---|---|---|
owner |
string | Yes | The workspace that owns the repository. |
name |
string | Yes | The repository’s name. |
environment |
string | Yes | The environment’s name, such as production. |
Body parameters
Section titled “Body parameters”Send a JSON object. Names are snake_case, as in responses; the camelCase spelling is accepted too.
| Name | Type | Required | Description |
|---|---|---|---|
wait_timer |
integer | No | Minutes each job waits before it may start, 0 to 43200. |
prevent_self_review |
boolean | No | Whoever started a run may not approve its jobs. |
reviewers |
array of objects or null | No | Up to 6 people or teams who may approve its jobs; empty for none. |
deployment_branch_policy |
object or null | No | null: every branch may deploy. protected_branches: only protected ones. custom_branch_policies: only those in branch_policies. |
branch_policies |
array of objects | No | With custom_branch_policies: the branches and tags that may deploy, at most 50. |
branch_policies[].name |
string | No | A pattern, such as main, release/* or v*. |
branch_policies[].type |
string | No | One of branch, tag. |
can_admins_bypass |
boolean | No | Admins may approve without being reviewers, skipping the wait. True unless you say. |
Example request
Section titled “Example request”curl -X PUT https://api.g1t.sh/repos/flagon-io/g1t/environments/production \ -H "Authorization: Bearer $G1T_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "wait_timer": 10, "prevent_self_review": true, "reviewers": [ { "type": "User", "name": "syntaqx" }, { "type": "Team", "name": "deployers" } ], "deployment_branch_policy": { "protected_branches": true, "custom_branch_policies": false } }'Example response
Section titled “Example response”A successful request answers 200 with:
{ "name": "production", "protection_rules": [ { "type": "required_reviewers", "prevent_self_review": true, "reviewers": [ { "type": "User", "reviewer": { "login": "syntaqx" } }, { "type": "Team", "reviewer": { "slug": "deployers" } } ] }, { "type": "wait_timer", "wait_timer": 10 }, { "type": "branch_policy" } ], "deployment_branch_policy": { "protected_branches": true, "custom_branch_policies": false }, "branch_policies": [], "can_admins_bypass": true, "protected": true, "updated_at": "2026-10-08T09:12:44.103Z", "updated_by": "syntaqx"}Errors
Section titled “Errors”A failed request answers with one of these statuses and a body like {"error": {"code": "not_found", "message": "Repository not found."}}. See 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 an agent token outside its repository. |
| 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. |