> ## Documentation Index
> Fetch the complete documentation index at: https://docs.b3os.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Product Offers

Fetch the purchasable offers for a retail product by URL or product ID, with ACCURATE Amazon Prime eligibility, fulfillment (FBA), availability, seller, and the per-offer shipping price — unlike product search, which runs logged-out and under-reports Prime. Returns each offer plus a recommended bestOffer (cheapest available, preferring free shipping / Prime) and, when shipping is known, a cent-accurate order quote. Ideal for: confirming Prime/fast shipping before ordering, getting an exact pre-checkout quote, deciding whether an item ships free.

Catalog action Integrations

Fetch the purchasable offers for a retail product by URL or product ID, with ACCURATE Amazon Prime eligibility, fulfillment (FBA), availability, seller, and the per-offer shipping price — unlike product search, which runs logged-out and under-reports Prime. Returns each offer plus a recommended bestOffer (cheapest available, preferring free shipping / Prime) and, when shipping is known, a cent-accurate order quote. Ideal for: confirming Prime/fast shipping before ordering, getting an exact pre-checkout quote, deciding whether an item ships free.


## At a Glance

| Field | Value |
| --- | --- |
| Action ID | `get-product-offers` |
| Category | Integrations |
| Connector | Not required |
| Requires gas | No |
| Funds movement | None declared |
| Tags | `shopping`, `products`, `details`, `quote`, `lookup`, `ecommerce`, `read` |

## Payload Schema

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `productUrl` | `string` | No | Product URL \(e.g. https://www.amazon.com/dp/B01N5IB20Q or https://www.walmart.com/ip/123456789\). A bare 10-character Amazon ASIN is also accepted. Provide this OR productId. |
| `productId` | `string` | No | Retailer product identifier \(Amazon ASIN or Walmart item ID\). Provide this OR productUrl. |
| `retailer` | `string` | No | Retailer for productId lookups. Default: 'amazon'. Ignored when productUrl is provided. |
| `quantity` | `number` | No | Quantity used to compute the order quote. Default: 1. |

## Result Schema

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `productId` | `string` | Yes | Retailer product identifier. |
| `retailer` | `string` | Yes | Retailer the product belongs to. |
| `productUrl` | `string` | Yes | Canonical product URL — pass to order-product. |
| `offerCount` | `number` | Yes | Number of offers returned. |
| `hasPrimeOffer` | `boolean` | Yes | True when any offer is Prime-eligible. |
| `hasFreeShippingOffer` | `boolean` | Yes | True when any offer ships free. |
| `requiresShippingConfirmation` | `boolean` | Yes | True when bestOffer is NOT a free-shipping/Prime buy — it carries a paid \(or unknown\) shipping fee. Surface bestOffer.shipPriceUsd to the user and have them accept the higher total or pick a Prime alternative BEFORE ordering; do not order silently \(the cap may not cover the shipping\). |
| `bestOffer` | `object \| null` | Yes | Recommended offer: cheapest available \(preferring New, free shipping, then Prime\). Null when no purchasable offer exists. |
| `offers` | `array` | Yes | All purchasable offers with accurate Prime / fulfillment / shipping data. |
| `orderQuote` | `object \| null` | Yes | Charge estimate built on bestOffer \(null when no priced offer\). When shippingKnown is true the cap is cent-accurate \(goods + tax buffer + real ship price\); otherwise it falls back to a flat shipping allowance. Pass estimatedMaxTotalCents to order-product as maxTotalCents for an exact charge. |
| `availability` | `string` | No | Machine-readable availability verdict: 'ok' = purchasable offer found; 'transient_miss' = the vendor's offer scrape came back empty \(retry — NOT proof of unavailability\); 'no_offers' = the listing has no offers at all \(possibly discontinued or a wrong/guessed product ID\); 'all_unavailable' = the listing exists but every offer is out of stock right now. |
| `note` | `string \| null` | No | Set ONLY when no purchasable offer exists: explains whether this is a transient lookup miss \(retry\), a listing with no offers at all \(possibly discontinued — or a wrong/guessed product ID; re-run search-products with fresh results\), or a listing whose offers are all out of stock. Null otherwise. |

## Examples

**Workflow node**

```json
{
  "type": "get-product-offers",
  "payload": {
    "productUrl": "https://example.com/webhook",
    "retailer": "amazon",
    "quantity": 1
  },
  "children": []
}
```
  **Test with API**

```bash
curl -X POST "https://api.b3os.org/v1/actions/get-product-offers/test" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "inputs": {
    "productUrl": "https://example.com/webhook",
    "retailer": "amazon",
    "quantity": 1
  }
}'
```

**Use expressions for dynamic values**

Payload fields can use workflow expressions such as `{{$trigger.body.amount}}`, `{{$nodes.fetch.result.price}}`, and `{{$props.asset}}` when the value should come from a trigger, prior node, or reusable workflow prop.