# GET /opportunities/:id/products

**Resource:** [Opportunities](./opportunities.md)  
**Scopes:** `opportunities:read`  
**Write operation:** no

List products attached to an opportunity with pricing and payment status. payment_status is only included in the response when the caller has invoices:read scope. Legacy alias: GET /deals/:id/products.

## Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `id` | path | uuid | yes | Opportunity ID |

## Response example

```json
{
  "data": [
    {
      "id": "opp-product-uuid",
      "product_id": "product-uuid",
      "quantity": 2,
      "unit_price": 950,
      "discount_percent": 10,
      "deposit_percent": null,
      "payment_status": "unpaid",
      "sort_order": 0,
      "crm_products": { "id": "product-uuid", "name": "Silver Package", "price": 1000, "currency": "AUD" }
    }
  ],
  "pagination": { "limit": 25, "has_more": false, "next_cursor": null, "prev_cursor": null },
  "meta": { "credits_remaining": 9499 }
}
```

---
Base URL: `https://api.trustpager.com/functions/v1/api/v1` — Auth: `Authorization: Bearer YOUR_API_KEY`