# List the files the session's pull request changed

`GET /o/{org}/p/{project}/sessions/{session}/changes`

Read from the run's GitHub pull request, so it works after the sandbox
is gone. A run with no pull request returns an empty list. When GitHub
cannot be read, the answer is still `200`, with the PR link, no files,
and `error_code` `CHANGES_NO_INSTALLATION` or `CHANGES_LIST_FAILED`.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `org` | path | string | yes | The org's slug or id. A caller with no role in the org gets `404`. |
| `project` | path | string | yes | A Project's handle (name) or id, resolved inside `{org}` — OR the reserved sentinel `_` meaning "no Project" (a direct-repo / repo-less dispatch on `POST`; "no Project constraint, resolve by session id alone" everywhere else). A real handle that doesn't match the session's actual Project is `404`.  |
| `session` | path | string | yes | The session's full id (`execution_id`). |

## Example request

```bash
curl "https://api.prix.dev/o/$RUSH_ORG/p/_/sessions/$SESSION_ID/changes" \
  -H "Authorization: Bearer $RUSH_API_KEY"
```

```typescript
const org = process.env.RUSH_ORG;
const sessionId = process.env.SESSION_ID;

const res = await fetch(`https://api.prix.dev/o/${org}/p/_/sessions/${sessionId}/changes`, {
  headers: {
    Authorization: `Bearer ${process.env.RUSH_API_KEY}`,
  },
});

console.log(res.status, await res.json());
```

```python
import os

import requests

org = os.environ["RUSH_ORG"]
session_id = os.environ["SESSION_ID"]

res = requests.get(
    f"https://api.prix.dev/o/{org}/p/_/sessions/{session_id}/changes",
    headers={"Authorization": f"Bearer {os.environ['RUSH_API_KEY']}"},
)

print(res.status_code, res.json())
```

## Responses

### 200

The changed files.

- `pr_url` (string | null, required)
- `pr_number` (integer | null, required)
- `files` (array of object, required)
  - `filename` (string, required)
  - `status` (string, required): GitHub's file status: added, modified, removed, renamed…
  - `additions` (integer, required)
  - `deletions` (integer, required)
  - `changes` (integer, required)
  - `patch` (string, optional): The unified diff, when GitHub returns one.
- `totals` (object, required)
  - `files` (integer, required)
  - `additions` (integer, required)
  - `deletions` (integer, required)
  - `changes` (integer, required)
- `error` (string, optional): Present only when the file list could not be read.
- `error_code` (string, optional, one of `CHANGES_NO_INSTALLATION`, `CHANGES_LIST_FAILED`)

### 401

No bearer, an unknown, revoked or expired one, or an API key on a route keys cannot call.

### 404

No such resource for the caller, including one that exists in an org the caller cannot see.

## Example response (200)

```json
{
  "pr_url": "https://github.com/acme/web/pull/412",
  "pr_number": 412,
  "files": [
    {
      "filename": "tests/checkout.spec.ts",
      "status": "modified",
      "additions": 6,
      "deletions": 2,
      "changes": 8
    }
  ],
  "totals": {
    "files": 1,
    "additions": 6,
    "deletions": 2,
    "changes": 8
  }
}
```
