Reviews
Start a code review of a pull request or a pushed branch over the REST API, and list every review with its outcome.
POST /v1/reviews runs the code review pipeline on demand; GET /v1/reviews lists what it has reviewed. Authenticate with your API key as a bearer token, like the rest of the API.
Start a review
POST /v1/reviews reviews an existing pull request, or a branch you pushed that has no pull request yet, and returns the scheduled review with 201. Name the repository with owner and repo, then exactly one target:
pull_request_numberreviews an existing pull request.branchreviews pushed work with no pull request. Ellipsis finds or creates a draft pull request for the branch (the review is delivered as pull request comments, so it needs one), marks itmanufactured: truein the response, and reuses it for later reviews of the same branch; close it when the work lands. Push to a sidecar branch such asellipsis/review/rest-period-rulesso a work-in-progress commit never lands on the branch you are working on, and passshato pin the review to the exact commit you pushed. A branch review always covers the branch's full range.
curl https://api.ellipsis.dev/v1/reviews \
-H "Authorization: Bearer $ELLIPSIS_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"owner": "splitshift-hq",
"repo": "splitshift-api",
"pull_request_number": 482
}'| Field | Type | Description |
|---|---|---|
owner | string | Required. The repository owner, e.g. splitshift-hq. |
repo | string | Required. The repository name, e.g. splitshift-api. |
pull_request_number | integer | The pull request to review. Pass this or branch, not both. |
branch | string | A pushed branch to review. Ellipsis finds or creates a draft pull request for it. |
sha | string | The commit you pushed to branch. Pins the reviewed range to exactly that commit. |
scope | object | Which range to review. kind is incremental (what changed since the last review, the default) or full (the whole pull request, ignoring earlier reviews). watermark and head pin the range to exact SHAs; full cannot be combined with watermark. |
post | boolean | Defaults to true. false runs the review without posting anything to GitHub; read the findings from the API instead. |
config_id | string | Run a specific saved review pipeline. |
config | object | An inline pipeline config to run instead. Pass at most one of config and config_id; with neither, the review runs your repository or account review default, else your synced pipeline file, else the built-in pipeline. |
The response is the review, freshly scheduled:
{
"id": "crun_4Xw8bJn2mQ9t",
"status": "scheduled",
"trigger": "api",
"repository": {
"id": 71203944,
"owner": "splitshift-hq",
"name": "splitshift-api"
},
"pull_request": {
"number": 482,
"url": "https://github.com/splitshift-hq/splitshift-api/pull/482",
"manufactured": false
},
"scope": {
"kind": "incremental",
"watermark": "3f9c2ab41d7e02c5b8a6f4d1e9c73b20a5d84f6c",
"head": "b71d4e08c2a95f3d6e10b7c4a8f25d9e3c61a0b7",
"empty": false
},
"reviewed_commits": [
{
"sha": "b71d4e08c2a95f3d6e10b7c4a8f25d9e3c61a0b7",
"message": "Reject overlapping shift trades",
"author_login": "priya-shah",
"author_avatar_url": "https://avatars.githubusercontent.com/u/5201153",
"authored_at": "2026-07-31T16:48:03+00:00"
}
],
"stages": [],
"configuration": {
"config_id": "crcfg_7Hq2mX4pKd3f",
"raw_yaml": null,
"effective_yaml": "ellipsis:\n version: v1\n kind: code_review\n name: Code review\nreview:\n - name: bugs\n claude:\n model: claude-opus-5\n system: ...\nfilter:\n name: gatekeeper\n claude:\n model: claude-opus-5\n system: ...\nbudget:\n run: 10.0\n"
},
"requested_by": {
"attribution_type": "api_key",
"attribution_id": "eak_9Qz3vT6wLm2r"
},
"post": true,
"posted_review_id": null,
"post_error": null,
"skip_reason": null,
"review_body": null,
"findings": [],
"counters": null,
"cost_millicents": 0,
"created_at": "2026-07-31T17:04:12+00:00",
"completed_at": null
}A review runs asynchronously. stages fill in as the pipeline's agents run, each with the session_id of the agent session behind it, which you can stream with the sessions API; review_body, findings, and counters are written as those sessions finish. Re-fetch with GET /v1/reviews/{review_id} until status is terminal. A review's status is one of scheduled, running, posting, completed, skipped, error, or cancelled.
Three outcomes to expect:
- An incremental review of a pull request whose head was already reviewed returns
201withstatus: "skipped", never an error: there is nothing new to review. - A second review of a pull request while one is still running is refused with
409. - Starting a review requires code review to be enabled for your account; while it is off, the request is refused with
403. A repository outside your installation is404.
List reviews
GET /v1/reviews returns recent reviews, newest first, across every trigger: reviews you started over the API or CLI and reviews that pushes triggered (trigger is api, cli, or webhook). Filtering by owner, repo, and pull_request_number answers "show me every review on this pull request".
curl "https://api.ellipsis.dev/v1/reviews?owner=splitshift-hq&repo=splitshift-api&pull_request_number=482" \
-H "Authorization: Bearer $ELLIPSIS_API_TOKEN"| Query | Type | Description |
|---|---|---|
owner / repo | string | Only reviews on this repository. Pass both together; one alone is 400. |
pull_request_number | integer | Only reviews on this pull request. Requires owner and repo. |
status | string | Only reviews with this status. |
limit | integer | Maximum reviews to return. Defaults to 50, capped at 200. |
The response is { "reviews": [...] } in the same shape start-a-review returns, minus the heavy fields: on the list, findings is always [] and configuration is null. Fetch one review by id for those.
{
"reviews": [
{
"id": "crun_4Xw8bJn2mQ9t",
"status": "completed",
"trigger": "api",
"repository": {
"id": 71203944,
"owner": "splitshift-hq",
"name": "splitshift-api"
},
"pull_request": {
"number": 482,
"url": "https://github.com/splitshift-hq/splitshift-api/pull/482",
"manufactured": false
},
"scope": {
"kind": "incremental",
"watermark": "3f9c2ab41d7e02c5b8a6f4d1e9c73b20a5d84f6c",
"head": "b71d4e08c2a95f3d6e10b7c4a8f25d9e3c61a0b7",
"empty": false
},
"reviewed_commits": [
{
"sha": "b71d4e08c2a95f3d6e10b7c4a8f25d9e3c61a0b7",
"message": "Reject overlapping shift trades",
"author_login": "priya-shah",
"author_avatar_url": "https://avatars.githubusercontent.com/u/5201153",
"authored_at": "2026-07-31T16:48:03+00:00"
}
],
"stages": [
{
"stage": "review",
"agent_name": "bugs",
"session_id": "session_2Nc7vR4qXw9k",
"status": "completed",
"cost_millicents": 312450,
"n_findings": 3,
"created_at": "2026-07-31T17:04:15+00:00",
"finalized_at": "2026-07-31T17:09:41+00:00",
"status_reason": null
},
{
"stage": "filter",
"agent_name": "gatekeeper",
"session_id": "session_8Tk3mB6yQp1z",
"status": "completed",
"cost_millicents": 148730,
"n_findings": 2,
"created_at": "2026-07-31T17:09:44+00:00",
"finalized_at": "2026-07-31T17:12:58+00:00",
"status_reason": null
}
],
"configuration": null,
"requested_by": {
"attribution_type": "api_key",
"attribution_id": "eak_9Qz3vT6wLm2r"
},
"post": true,
"posted_review_id": 2841773301,
"post_error": null,
"skip_reason": null,
"review_body": "Reviewed the shift-trade validation changes. Two findings worth a look; details inline.",
"findings": [],
"counters": {
"n_raw_lines": 5,
"n_parsed": 5,
"n_dropped": 0,
"n_coerced": 1,
"n_anchor_valid": 4,
"n_snapped": 1,
"n_not_commentable": 0,
"parser_version": "1"
},
"cost_millicents": 461180,
"created_at": "2026-07-31T17:04:12+00:00",
"completed_at": "2026-07-31T17:13:06+00:00"
}
]
}