GitHub Copilot code review works well from the pull request UI — you click a button, an AI reviews your diff, and feedback appears within seconds. The problem starts when you try to trigger that same review from a CI/CD pipeline, a GitHub Action, or any automated workflow. The API behavior is undocumented in places that matter, and the failure mode is the worst kind: silent.

Here's what I found after more trial and error than I'd like to admit.

The Problem

A reasonable assumption would be that requesting a code review from Copilot works the same way as requesting one from a teammate. It doesn't. If you pass "Copilot" or "copilot" as a reviewer name to GitHub's REST API, you'll get back a 201 Created response — clean, successful, no error. But nothing actually happens. The request vanishes without a trace.

Why is this a problem worth writing about? Because the API gives you every reason to believe it worked. There's no validation error, no warning header, no indication that your reviewer name was ignored. You move on, your pipeline moves on, and the review never arrives.

Silent Failure

This is, in my opinion, a genuinely bad API design choice. Silent failure is always worse than a loud error.

Three Working Approaches

1. GitHub CLI (simplest — requires gh ≥ 2.88.0)

bash
gh pr edit <PR#> --add-reviewer "@copilot"

If your CI environment already has gh installed, this is the path of least resistance. The CLI handles the @copilot alias internally, translating it to the correct bot identity before the API call goes out. You don't need to know (or care about) the underlying bot login name.

2. REST API

For direct API calls, the correct bot login is copilot-pull-request-reviewer[bot]:

bash
gh api repos/OWNER/REPO/pulls/PR_NUMBER/requested_reviewers \
  --method POST \
  --input - <<'EOF'
{"reviewers":["copilot-pull-request-reviewer[bot]"]}
EOF

Or with curl:

bash
curl -X POST \
  -H "Authorization: Bearer $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github+json" \
  https://api.github.com/repos/OWNER/REPO/pulls/PR_NUMBER/requested_reviewers \
  -d '{"reviewers":["copilot-pull-request-reviewer[bot]"]}'

That bot login — copilot-pull-request-reviewer[bot] — doesn't appear in any obvious documentation. It's not copilot[bot] (which is the chat assistant), and it's not Copilot as a display name. GitHub maintains a separate, dedicated bot account specifically for the code review feature. How would you discover this on your own? Good question.

3. GraphQL API

GitHub's GraphQL API treats bot users differently from human users. You'll need the botLogins field rather than userLogins:

graphql
mutation {
  requestReviewsByLogin(input: {
    pullRequestId: "<PR_NODE_ID>",
    botLogins: ["copilot-pull-request-reviewer[bot]"],
    union: false
  }) {
    clientMutationId
  }
}

To get the PR node ID:

bash
gh api repos/OWNER/REPO/pulls/PR_NUMBER --jq '.node_id'

The Gotchas

Getting the initial request to work is only half the battle. These are the follow-on issues that will cost you debugging time if you don't know about them upfront.

Silent failure on unrecognized names. The REST API returns a success response even when it completely ignores a reviewer name you've passed. A typo in the bot login produces no error and no review. Your only reliable option is to verify the reviewer actually appeared by querying the PR's requested reviewers list after the POST.

Force-pushing can invalidate review state. If your workflow force-pushes (rebase, squash, amend) after requesting a Copilot review, you may need to re-request it. GitHub dismisses stale reviews on new commits when branch protection rules are configured for it, and I've observed pending review requests silently dropped after force pushes in practice.

Copilot typically responds in under 30 seconds, according to GitHub's documentation, though larger PRs can take longer. If you're polling for the review result, wait at least 15–20 seconds before your first check.

Names That Don't Work

All of these fail silently via the REST API: Copilot, copilot, @copilot, copilot[bot], copilot-swe-agent[bot], github-copilot[bot]. Only copilot-pull-request-reviewer[bot] works.

Why This Matters for Agentic Workflows

Automated pull request workflows are becoming more common, and reliable programmatic review triggering is a prerequisite for several patterns that teams are adopting now:

In my own workflows, I've landed on a pattern that issues the review request and then immediately verifies it took effect:

bash
#!/usr/bin/env bash
set -euo pipefail

PR_NUMBER="$1"
REPO="$2"

# Request the review
gh api "repos/${REPO}/pulls/${PR_NUMBER}/requested_reviewers" \
  --method POST \
  --input - <<'EOF'
{"reviewers":["copilot-pull-request-reviewer[bot]"]}
EOF

# Verify it was actually requested
sleep 2
REVIEWERS=$(gh api "repos/${REPO}/pulls/${PR_NUMBER}/requested_reviewers" \
  --jq '.users[].login')

if echo "$REVIEWERS" | grep -q "copilot-pull-request-reviewer"; then
  echo "Copilot review successfully requested on PR #${PR_NUMBER}"
else
  echo "WARNING: Copilot review request may have failed" >&2
  exit 1
fi

That verification step matters more than you'd expect. Because the POST returns a success status regardless of whether the reviewer name was valid, the only way to confirm the request went through is to check the PR's reviewer list after the fact.

Wrapping Up

Copilot code review is a useful tool for getting fast, automated feedback on pull requests. However, the API surface for triggering it programmatically has real rough edges — particularly the silent failure behavior, which violates the principle of least astonishment and turns simple debugging into guesswork. Until GitHub improves the error handling here, the essential detail to remember is the bot login: copilot-pull-request-reviewer[bot]. Everything else follows from that.