> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://help.swellsystem.com/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# Reviews API

# Reviews API

The Reviews API provides REST endpoints for approvals, revision requests, and annotations. All endpoints require authentication (`Authorization: Bearer {token}`) and are tenant-scoped.

## Base Path

```
/v1/projects/{project}/...
```

Replace `{project}` with the project ID.

## Approvals

### List Approvals
```
GET /v1/projects/{project}/approvals
```

Returns all approvals for the project.

### Create Approval (Request Approval)
```
POST /v1/projects/{project}/approvals
Content-Type: application/json

{
  "type": "deliverable|milestone|final",
  "comments": "Optional comment"
}
```

### Get Approval
```
GET /v1/projects/{project}/approvals/{id}
```

### Approve
```
POST /v1/projects/{project}/approvals/{id}/approve
Content-Type: application/json

{
  "comments": "Optional approval note"
}
```

### Reject
```
POST /v1/projects/{project}/approvals/{id}/reject
Content-Type: application/json

{
  "comments": "Reason for rejection"
}
```

### Request Changes
```
POST /v1/projects/{project}/approvals/{id}/request-changes
Content-Type: application/json

{
  "comments": "What needs to change"
}
```

## Revision Requests

### List Revision Requests
```
GET /v1/projects/{project}/revision-requests
```

### Create Revision Request
```
POST /v1/projects/{project}/revision-requests
Content-Type: application/json

{
  "title": "Update logo color",
  "description": "Change primary blue to #0066CC",
  "assigned_to_user_id": 5,
  "due_date": "2025-02-15",
  "approval_id": 1
}
```

### Update Revision Request
```
PATCH /v1/projects/{project}/revision-requests/{id}
Content-Type: application/json

{
  "status": "completed",
  "completion_notes": "Done"
}
```

## Annotations

### List Annotations
```
GET /v1/projects/{project}/annotations
```

Query parameters:
- `target_type` – `project_file` or `url`
- `target_id` – File ID (when target_type=project_file)
- `target_url` – URL (when target_type=url)
- `page_number` – PDF page (optional)
- `status` – `open`, `resolved`, `snoozed`

### Create Annotation
```
POST /v1/projects/{project}/annotations
Content-Type: application/json

{
  "target_type": "project_file",
  "target_id": 42,
  "target_url": null,
  "page_number": 1,
  "position_x": 50.5,
  "position_y": 30.2,
  "title": "Fix alignment",
  "screenshot_path": "annotations/1/screenshot.png",
  "is_internal": false,
  "assigned_to_id": 5
}
```

For URL targets:
```json
{
  "target_type": "url",
  "target_url": "https://example.com/preview",
  "position_x": 25,
  "position_y": 60
}
```

### Get Annotation
```
GET /v1/projects/{project}/annotations/{id}
```

Returns the annotation with its comments.

### Update Annotation
```
PATCH /v1/projects/{project}/annotations/{id}
Content-Type: application/json

{
  "status": "resolved",
  "assigned_to_id": 5,
  "title": "Updated title"
}
```

### Add Comment
```
POST /v1/projects/{project}/annotations/{id}/comments
Content-Type: application/json

{
  "body": "Looks good. @[user_id] please verify.",
  "parent_id": null
}
```

Use `parent_id` for threaded replies.

### Upload Screenshot
```
POST /v1/projects/{project}/annotations/upload-screenshot
Content-Type: multipart/form-data

file: (image file)
```

Returns `{ "path": "...", "url": "..." }` for use in the create annotation payload.

## Webhook Events

Subscribe to Reviews events in your webhook subscriptions:

- `approval.requested`
- `approval.approved`
- `approval.rejected`
- `approval.changes_requested`
- `revision_request.created`
- `revision_request.completed`
- `revision_request.rejected`
- `annotation.created`
- `annotation.updated`
- `annotation.resolved`
- `annotation.mention`

## Plan Requirements

The Reviews module must be active for your tenant (Professional, Business, or add-on). API requests will return `403` if the module is not enabled.
