Skip to content

Create a repository ruleset: name, enforcement (active, evaluate or disabled; active by default), target (branch or tag), conditions.ref_name (include and exclude patterns), bypass_actors (each a kind: role, team, user, token or g1t, a value, and a mode: always or pull_requests; nobody bypasses unless listed, g1t included) and rules (each a type, its parameters, and applies_to: everyone, agents or people).

POST/repos/{owner}/{name}/rulesets

Rule types: creation, update, deletion, non_fast_forward, required_linear_history, required_signatures, pull_request, required_status_checks, merge_queue, required_deployments, commit_message_pattern, commit_author_email_pattern, committer_email_pattern, branch_name_pattern, tag_name_pattern, file_path_restriction, file_extension_restriction, max_file_size, max_file_path_length, max_files_changed, secret_scanning, confidence_threshold, cost_cap, path_review, merge_window and agent_auto_merge. Several rulesets stack: every rule of each holds. Takes the Admin role. Returns the ruleset as saved, tidied.

Parameters left out take their defaults, and the ruleset comes back as saved: patterns trimmed, roles and teams lowercased. A pattern that does not compile, or a rule the target cannot hold (a pull request rule on tags), is refused with invalid and says why.

  • Authentication: Required. Send an access token as Authorization: Bearer.
  • MCP tool: repository with action create_ruleset, and the same inputs
  • Scope: An access token needs repo:admin.
Name Type Required Description
owner string Yes The workspace that owns the repository.
name string Yes The repository’s name.

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

Name Type Required Description
ruleset_name string No What people call it, at most 100 characters. A ruleset as exported names it name, which is read too.
enforcement string No active: its rules hold. evaluate: nothing is refused, and what would have been is recorded. disabled: kept, not evaluated. Default active. One of active, evaluate, disabled.
target string No What its name conditions match. Default branch. One of branch, tag.
conditions object No
conditions.ref_name object No Which branches or tags: include and exclude, each a list of fnmatch patterns (* within a path segment, ** across them), ~DEFAULT_BRANCH or ~ALL.
conditions.ref_name.include array of strings No
conditions.ref_name.exclude array of strings No
bypass_actors array of objects No Who it does not hold for. Nobody bypasses unless listed, g1t included. kind role takes read, triage, write, maintain, admin (that role or higher) or owner; team its slug or workspace/slug; user a username; token a token id, or workspace for any of the workspace’s tokens; g1t no value. mode always (pushes and merges) or pull_requests (merges only; a person merging asks to, with bypass_rules).
bypass_actors[].kind string Yes One of role, team, user, token, g1t.
bypass_actors[].value string No
bypass_actors[].mode string No One of always, pull_requests.
rules array of objects No Its rules. Each: type, parameters (left-out parameters take their defaults) and applies_to (everyone, agents or people). See the Rules guide for every type’s parameters.
rules[].type string Yes
rules[].parameters object No
rules[].applies_to string No One of everyone, agents, people.
curl -X POST https://api.g1t.sh/repos/flagon-io/hello/rulesets \
-H "Authorization: Bearer $G1T_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"ruleset_name": "Protect main",
"enforcement": "active",
"target": "branch",
"conditions": {
"ref_name": {
"include": [
"~DEFAULT_BRANCH"
],
"exclude": []
}
},
"bypass_actors": [
{
"kind": "role",
"value": "admin",
"mode": "pull_requests"
}
],
"rules": [
{
"type": "deletion",
"parameters": {},
"applies_to": "everyone"
},
{
"type": "non_fast_forward",
"parameters": {},
"applies_to": "everyone"
},
{
"type": "pull_request",
"parameters": {
"required_approvals": 1,
"count_agent_approvals": true,
"dismiss_stale_reviews_on_push": true,
"require_code_owner_review": true,
"require_last_push_approval": false,
"allowed_merge_methods": []
},
"applies_to": "everyone"
},
{
"type": "required_status_checks",
"parameters": {
"checks": [
{
"context": "CI",
"integration": "actions"
}
],
"strict": true,
"paths": [],
"allow_bypass_on_merge": false
},
"applies_to": "everyone"
},
{
"type": "pull_request",
"parameters": {
"required_approvals": 1,
"count_agent_approvals": false,
"dismiss_stale_reviews_on_push": false,
"require_code_owner_review": false,
"require_last_push_approval": false,
"allowed_merge_methods": []
},
"applies_to": "agents"
},
{
"type": "file_path_restriction",
"parameters": {
"restricted_file_paths": [
".g1t/workflows/**",
"CODEOWNERS"
]
},
"applies_to": "agents"
}
]
}'

A successful request answers 200 with:

{
"id": "rs_01kq3a8b9c0d1e2f3g4h5j6k7m",
"level": "repository",
"workspace": "flagon-io",
"repo_id": "rep_01kq0f3a7b8c9d0e1f2g3h4j5k",
"repository": "flagon-io/hello",
"name": "Protect main",
"enforcement": "active",
"target": "branch",
"conditions": {
"ref_name": {
"include": [
"~DEFAULT_BRANCH"
],
"exclude": []
}
},
"bypass_actors": [
{
"kind": "role",
"value": "admin",
"mode": "pull_requests"
}
],
"rules": [
{
"type": "deletion",
"parameters": {},
"applies_to": "everyone"
},
{
"type": "non_fast_forward",
"parameters": {},
"applies_to": "everyone"
},
{
"type": "pull_request",
"parameters": {
"required_approvals": 1,
"count_agent_approvals": true,
"dismiss_stale_reviews_on_push": true,
"require_code_owner_review": true,
"require_last_push_approval": false,
"allowed_merge_methods": []
},
"applies_to": "everyone"
},
{
"type": "required_status_checks",
"parameters": {
"checks": [
{
"context": "CI",
"integration": "actions"
}
],
"strict": true,
"paths": [],
"allow_bypass_on_merge": false
},
"applies_to": "everyone"
},
{
"type": "pull_request",
"parameters": {
"required_approvals": 1,
"count_agent_approvals": false,
"dismiss_stale_reviews_on_push": false,
"require_code_owner_review": false,
"require_last_push_approval": false,
"allowed_merge_methods": []
},
"applies_to": "agents"
},
{
"type": "file_path_restriction",
"parameters": {
"restricted_file_paths": [
".g1t/workflows/**",
"CODEOWNERS"
]
},
"applies_to": "agents"
}
],
"created_by": "syntaqx",
"created_at": "2026-10-07T14:02:11.318Z",
"updated_by": "syntaqx",
"updated_at": "2026-10-07T14:02:11.318Z"
}

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.