# Pull Request Reviews API Reference

## Endpoints

### List All Reviews

```
GET /repos/{owner}/{repo}/pulls/{index}/reviews
```

**Parameters:**

| Parameter | Type | Description              |
|-----------|------|--------------------------|
| page      | int  | Page number (1-based)    |
| limit     | int  | Page size                |

```bash
curl -s \
  -H "Authorization: token ${FORGEJO_PAT}" \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews"
```

### Create a Review

```
POST /repos/{owner}/{repo}/pulls/{index}/reviews
```

**CreatePullReviewOptions:**

| Field     | Type                       | Required | Description                                      |
|-----------|----------------------------|----------|--------------------------------------------------|
| body      | string                     | no       | Top-level review comment                         |
| event     | string                     | yes      | `"APPROVED"`, `"REQUEST_CHANGES"`, or `"COMMENT"` |
| commit_id | string                     | no       | Specific commit SHA to review                    |
| comments  | array[CreatePullReviewComment] | no   | Inline comments on specific lines                |

**CreatePullReviewComment:**

| Field        | Type   | Required | Description                              |
|--------------|--------|----------|------------------------------------------|
| path         | string | yes      | File path relative to repo root          |
| body         | string | yes      | Comment body (markdown)                  |
| new_position | int    | no       | Line number in the new version of the file |
| old_position | int    | no       | Line number in the old version of the file |

```bash
# Create a review with inline comments
curl -s -X POST \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Generally looks good, but a few issues to address.",
    "event": "REQUEST_CHANGES",
    "comments": [
      {
        "path": "src/auth/handler.go",
        "body": "This should validate the token expiry before proceeding.",
        "new_position": 45
      },
      {
        "path": "src/auth/handler.go",
        "body": "Consider using a constant for this magic number.",
        "new_position": 72
      },
      {
        "path": "src/models/user.go",
        "body": "The old validation was more thorough. Why was it removed?",
        "old_position": 30
      }
    ]
  }' \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews"

# Approve a PR
curl -s -X POST \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "LGTM! Clean implementation.",
    "event": "APPROVED"
  }' \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews"

# Leave a general comment review (neither approve nor request changes)
curl -s -X POST \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Some thoughts on the approach - not blocking.",
    "event": "COMMENT"
  }' \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews"

# Review a specific commit
curl -s -X POST \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Reviewing the latest fixup commit.",
    "event": "COMMENT",
    "commit_id": "abc123def456789"
  }' \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews"
```

### Get a Specific Review

```
GET /repos/{owner}/{repo}/pulls/{index}/reviews/{id}
```

```bash
curl -s \
  -H "Authorization: token ${FORGEJO_PAT}" \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}"
```

### Submit a Pending Review

```
POST /repos/{owner}/{repo}/pulls/{index}/reviews/{id}
```

Submits a review that was created in a pending state. This finalizes the review and makes it visible.

**SubmitPullReviewOptions:**

| Field | Type   | Required | Description                                      |
|-------|--------|----------|--------------------------------------------------|
| body  | string | no       | Review body message                              |
| event | string | yes      | `"APPROVED"`, `"REQUEST_CHANGES"`, or `"COMMENT"` |

```bash
# Submit a pending review as approved
curl -s -X POST \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "All issues addressed. Approving.",
    "event": "APPROVED"
  }' \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}"
```

### Delete a Pending Review

```
DELETE /repos/{owner}/{repo}/pulls/{index}/reviews/{id}
```

Only pending (not yet submitted) reviews can be deleted.

```bash
curl -s -X DELETE \
  -H "Authorization: token ${FORGEJO_PAT}" \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}"
```

---

## Review Comments

### List Comments on a Review

```
GET /repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments
```

```bash
curl -s \
  -H "Authorization: token ${FORGEJO_PAT}" \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}/comments"
```

### Add a Comment to an Existing Review

```
POST /repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments
```

**CreatePullReviewComment:**

| Field        | Type   | Required | Description                              |
|--------------|--------|----------|------------------------------------------|
| path         | string | yes      | File path relative to repo root          |
| body         | string | yes      | Comment body (markdown)                  |
| new_position | int    | no       | Line number in the new version of the file |
| old_position | int    | no       | Line number in the old version of the file |

```bash
curl -s -X POST \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "path": "pkg/server/routes.go",
    "body": "This route should require authentication middleware.",
    "new_position": 88
  }' \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}/comments"
```

### Get a Specific Review Comment

```
GET /repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments/{comment}
```

```bash
curl -s \
  -H "Authorization: token ${FORGEJO_PAT}" \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}/comments/{comment_id}"
```

### Delete a Review Comment

```
DELETE /repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments/{comment}
```

```bash
curl -s -X DELETE \
  -H "Authorization: token ${FORGEJO_PAT}" \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}/comments/{comment_id}"
```

---

## Dismissing and Undismissing Reviews

### Dismiss a Review

```
POST /repos/{owner}/{repo}/pulls/{index}/reviews/{id}/dismissals
```

Dismisses a review so it no longer blocks merging. Requires admin or repository owner permissions.

| Field   | Type   | Required | Description          |
|---------|--------|----------|----------------------|
| message | string | no       | Reason for dismissal |

```bash
curl -s -X POST \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Reviewer is out of office. Changes were verified by another team member."
  }' \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}/dismissals"
```

### Undismiss a Review

```
POST /repos/{owner}/{repo}/pulls/{index}/reviews/{id}/undismissals
```

Restores a previously dismissed review.

```bash
curl -s -X POST \
  -H "Authorization: token ${FORGEJO_PAT}" \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}/undismissals"
```

---

## Requesting Reviewers

### Request Reviewers

```
POST /repos/{owner}/{repo}/pulls/{index}/requested_reviewers
```

**Request body:**

| Field          | Type          | Description                    |
|----------------|---------------|--------------------------------|
| reviewers      | array[string] | Usernames to request review from |
| team_reviewers | array[string] | Team names to request review from |

```bash
# Request individual reviewers
curl -s -X POST \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "reviewers": ["{reviewer1}", "{reviewer2}"]
  }' \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/requested_reviewers"

# Request team reviewers
curl -s -X POST \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "team_reviewers": ["security-team", "backend-team"]
  }' \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/requested_reviewers"

# Request both individual and team reviewers
curl -s -X POST \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "reviewers": ["{reviewer}"],
    "team_reviewers": ["security-team"]
  }' \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/requested_reviewers"
```

### Cancel Review Requests

```
DELETE /repos/{owner}/{repo}/pulls/{index}/requested_reviewers
```

Uses the same body format as requesting reviewers.

```bash
# Cancel individual review requests
curl -s -X DELETE \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "reviewers": ["{reviewer}"]
  }' \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/requested_reviewers"

# Cancel team review requests
curl -s -X DELETE \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "team_reviewers": ["backend-team"]
  }' \
  "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/{index}/requested_reviewers"
```

---

## PullReview Response Object

| Field              | Type          | Description                                       |
|--------------------|---------------|---------------------------------------------------|
| id                 | int           | Review ID                                         |
| reviewer           | User          | User who created the review                       |
| state              | string        | Review state (see below)                          |
| body               | string        | Review body text                                  |
| commit_id          | string        | Commit SHA the review was made against             |
| submitted_at       | string        | Timestamp (ISO 8601)                              |
| html_url           | string        | Web URL of the review                             |
| pull_request_url   | string        | API URL of the associated PR                      |
| comments_count     | int           | Number of inline comments in this review          |
| official           | boolean       | Whether this is an official (CODEOWNERS) review   |
| dismissed          | boolean       | Whether the review has been dismissed              |
| stale              | boolean       | Whether the review is stale (code has changed)     |
| team               | Team/null     | Team associated with this review (if team review)  |

### Review States

| State              | Description                                 |
|--------------------|---------------------------------------------|
| APPROVED           | Reviewer approved the changes               |
| REQUEST_CHANGES    | Reviewer requested changes                  |
| COMMENT            | General comment, neither approval nor block  |
| PENDING            | Review has not yet been submitted            |
| REQUEST_REVIEW     | Review has been requested but not started    |

---

## Complete Workflow Example

```bash
#!/bin/bash
# Full review workflow: request reviewers, review with comments, approve, merge

OWNER="{owner}"
REPO="{repo}"
PR_INDEX="{index}"

# 1. Request reviewers
curl -s -X POST \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{"reviewers": ["{reviewer1}", "{reviewer2}"], "team_reviewers": ["security-team"]}' \
  "${FORGEJO_URL}/api/v1/repos/${OWNER}/${REPO}/pulls/${PR_INDEX}/requested_reviewers"

# 2. Create a review requesting changes
REVIEW=$(curl -s -X POST \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "A few issues need fixing before merge.",
    "event": "REQUEST_CHANGES",
    "comments": [
      {
        "path": "main.go",
        "body": "Missing error handling here.",
        "new_position": 55
      }
    ]
  }' \
  "${FORGEJO_URL}/api/v1/repos/${OWNER}/${REPO}/pulls/${PR_INDEX}/reviews")

REVIEW_ID=$(echo "$REVIEW" | jq '.id')
echo "Created review: $REVIEW_ID"

# 3. After fixes are pushed, approve the PR
curl -s -X POST \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Issues addressed. LGTM!",
    "event": "APPROVED"
  }' \
  "${FORGEJO_URL}/api/v1/repos/${OWNER}/${REPO}/pulls/${PR_INDEX}/reviews"

# 4. Dismiss an outdated blocking review if needed
curl -s -X POST \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{"message": "Issues have been resolved in latest push."}' \
  "${FORGEJO_URL}/api/v1/repos/${OWNER}/${REPO}/pulls/${PR_INDEX}/reviews/${REVIEW_ID}/dismissals"

# 5. List all reviews to verify state
curl -s \
  -H "Authorization: token ${FORGEJO_PAT}" \
  "${FORGEJO_URL}/api/v1/repos/${OWNER}/${REPO}/pulls/${PR_INDEX}/reviews" | \
  jq '.[] | {id: .id, reviewer: .reviewer.login, state: .state, dismissed: .dismissed}'
```
