Decisions and why
Explain a line
Why a line of a file is the way it is: the commit that last changed it (by blame, at ref or the default branch), the merged pull request it arrived in, that pull request's issue, the decision records on the pull request, and the session entries recorded around that commit (what was said and the tool calls that touched the file, at most eight). pull, issue, decisions and sessions are empty when the commit did not arrive through a pull request.
GET
/repos/{owner}/{name}/whyref reads the file at a branch, tag or commit. See sessions and why-blame.
- Authentication: Optional. Public data can be read without a token; send one to see what is private.
- MCP tool:
repositorywithactionwhy, and the same inputs - Scope: An access token needs
code:read.
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. |
Query parameters
Section titled “Query parameters”| Name | Type | Required | Description |
|---|---|---|---|
path |
string | Yes | The file, from the repository’s root, such as “src/main.rs”. |
line |
integer | Yes | The line, counted from 1. |
ref |
string | No | A branch, tag or commit. The default branch if not given. |
Example request
Section titled “Example request”curl "https://api.g1t.sh/repos/flagon-io/hello/why?path=src%2Fconfig.rs&line=42" \ -H "Authorization: Bearer $G1T_TOKEN"Example response
Section titled “Example response”A successful request answers 200 with:
{ "path": "src/config.rs", "line": 42, "commit": { "hash": "7d3e9a1c5b2f4e6a8c0d2e4f6a8b0c2d4e6f8a0b", "tree_hash": "c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0", "message": "Read retry_limit, as #12 names it", "author": { "name": "Ana Lima", "email": "ana@example.com" }, "parents": [ "4be1c0d9a2f3e4b5c6d7e8f90a1b2c3d4e5f6a7b" ], "authored_at": "2026-10-12T15:29:02Z" }, "pull": { "number": 14, "title": "Retry failed webhook deliveries", "author": "ana", "agent": "claude-code", "merged_by": "g1t", "merged_at": "2026-10-12T15:52:18.330Z" }, "issue": { "number": 9, "title": "Webhook deliveries are not retried", "state": "closed", "body": "A delivery that times out is never sent again." }, "decisions": [ { "id": "dec_01kpz8m2q4r6s8t0v2w4x6y8za", "issue": 9, "pull": 14, "session_id": null, "actor": null, "kind": "integration_failure", "confidence": "tested", "summary": "#14 failed in the merge queue together with #12: `CI / merge_group` failed when they were combined.", "evidence": { "commit": "4be1c0d9a2f3e4b5c6d7e8f90a1b2c3d4e5f6a7b", "check": { "name": "CI / merge_group", "conclusion": "failure", "url": "https://g1t.sh/acme/web/actions/runs/run_01kpz8k0" }, "combination": [ 11, 12, 14 ], "other_pulls": [ 11, 12 ], "suspects": [ 12 ], "bisected": true, "landed": [] }, "created_at": "2026-10-12T15:04:11.204Z" }, { "id": "dec_01kpz9a1b3c5d7e9f1g3h5j7kb", "issue": 9, "pull": 14, "session_id": "ses_01kpz7x9y1z3a5b7c9d1e3f5gh", "actor": "ana", "kind": "fix", "confidence": "claimed", "summary": "Renamed the config key #12 also introduced, so both read retry_limit.", "evidence": { "commit": "7d3e9a1c5b2f4e6a8c0d2e4f6a8b0c2d4e6f8a0b" }, "created_at": "2026-10-12T15:31:40.019Z" } ], "sessions": [ { "seq": 31, "kind": "message", "text": "#12 renamed retries to retry_limit; reading the new name here.", "tool": null, "commit": null, "at": "2026-10-12T15:27:40.118Z" } ]}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 a token without the scope it needs. |
| 404 | not_found |
It does not exist, or you cannot see it. |
| 422 | invalid |
The input is not valid. message says which field and why. |