Amazon coupons live on their own promotion pages. Each page lists the discount, the expiry date, how to claim it, the terms, and every product the coupon applies to. That's useful data if you run a deal site, monitor a competitor's discounts, or want to know the real price of a product after the coupon.

PLACEHOLDER: Amazon promotion page with the promotion ID highlighted in the address bar
Amazon promotion page

The problem is that Amazon has no public API endpoint that returns a coupon page's terms and qualifying products. Scraping the page yourself is also tricky because the product grid loads with JavaScript, making a DIY scraper harder to maintain.

In this tutorial, you'll use the Amazon Promotion API from SerpApi to retrieve promotion data as clean JSON or Markdown. You'll also export qualifying products to a CSV file and build a small script to check whether your coupons are still active.

What data does the Amazon Promotion API return?

Each request takes one promotion ID and returns a promotion_results object with:

  • title: the coupon headline, for example Save 25% on your Subscribe & Save subscription.
  • saving_info: what the discount is and how it's applied.
  • schedule: when the promotion runs, such as Limited-time offer or a date range.
  • expiration: the coupon's expiry date.
  • how_to_claim: the steps a shopper follows to use the coupon.
  • terms: the terms and conditions, grouped into sections with a title, text, and items.
  • link: the Amazon promotion page URL.

If you add include_products=true, you also get qualifying_items, the products the coupon applies to. Each item includes its asin, title, brand, price, extracted_price, rating, reviews, prime, merchant_id, and a serpapi_amazon_product_link, which is a ready-made Amazon Product API request for that item.

Here's a trimmed response for promotion ASV27IGU190N with include_products=true:

{
  "promotion_results": {
    "promotion_id": "ASV27IGU190N",
    "title": "Save 25% on your Subscribe & Save subscription",
    "saving_info": "25% extra savings on the first order, applied at checkout. Coupons may be subject to a maximum dollar value, which will be reflected at checkout if applicable.",
    "schedule": "Limited-time offer",
    "expiration": "Coupon Expiry Date January 1, 2027",
    "how_to_claim": [
      "Select the Clip Coupon button.",
      "Add 1 item from the products below to your Cart using the Add to Cart button or select See Options for specific product variations.",
      ...
    ],
    "terms": [
      {
        "title": "How to redeem a coupon:",
        "items": [...]
      },
      ...
    ],
    "link": "https://www.amazon.com/promotion/psp/ASV27IGU190N"
  },
  "qualifying_items": [
    {
      "position": 1,
      "asin": "B0CDHNX333",
      "serpapi_amazon_product_link": "https://serpapi.com/search.json?amazon_domain=amazon.com&asin=B0CDHNX333&device=desktop&engine=amazon_product",
      "title": "Orgain Organic Kids Dairy 8g Protein Shake, Fruity Cereal, 8.25 oz, 12pk | ...",
      "brand": "Orgain",
      "price": "$19.49",
      "extracted_price": 19.49,
      "rating": 4.5,
      "reviews": 644,
      "prime": true,
      "merchant_id": "ATVPDKIKX0DER"
    },
    ...
  ]
}
PLACEHOLDER: SerpApi playground showing the Amazon Promotion API response
SerpApi returns Amazon promotion pages in a structured output

Getting started with SerpApi

You need a free SerpApi account before you can use the API. You can upgrade to a paid plan later if you need more searches, faster speeds, or additional features.

First, create an account and verify your email. Then grab your API key from your account dashboard and save it in an environment variable. Set it in your terminal, replacing the placeholder with your real key:

export SERPAPI_API_KEY="YOUR_SERPAPI_API_KEY"

The free plan includes 250 searches per month, and you can try any promotion live in the interactive playground before writing code.

🔐
You should store your API key in a safe location if you're sharing or publishing your code. If it's ever leaked, you can generate a new one from the dashboard.

Install the SerpApi library (optional)

SerpApi has official libraries for Python, JavaScript, Ruby, Java, and more. They're a thin wrapper around the API and aren't required. The API works just as well with plain GET requests, cURL, or fetch() in Node.js.

Review the Amazon Promotion API documentation

The engine is amazon_promotion, and the only required parameter is promotion_id. Other useful parameters:

  • include_products: set to true to also get the qualifying products. Responses take longer with this on.
  • amazon_domain: the Amazon marketplace to use, such as amazon.co.uk or amazon.de. Defaults to amazon.com. See the supported Amazon domains. amazon.cn isn't supported because Amazon no longer serves promotion pages there.
  • language: the page language, such as es_US on amazon.com. See the supported Amazon languages.
  • output: set to md for a token-efficient Markdown response.

For the full field reference and live examples, see the Amazon Promotion API documentation.

PLACEHOLDER: Amazon Promotion API documentation page
SerpApi's Amazon Promotion API documentation

Find the promotion ID

The promotion ID is in the URL of every Amazon coupon page. Open a coupon from a product page (the "Shop items" or "Terms" link next to the coupon badge), and copy the code after /promotion/psp/ or /promotion/details/popup/:

Promotion ID location

How to scrape Amazon coupons

The results are same across every library, so use whichever method fits your stack.

GET request

This gets the coupon details for a promotion ASV27IGU190N:

https://serpapi.com/search.json?engine=amazon_promotion&promotion_id=ASV27IGU190N&api_key=SERPAPI_API_KEY

By default, you get JSON, but you can request Markdown by adding output=md (or using the /search.md endpoint, or the Accept: text/markdown header). Markdown is handy when you feed coupon terms to an LLM or AI agent:

https://serpapi.com/search.json?engine=amazon_promotion&promotion_id=ASV27IGU190N&output=md&api_key=SERPAPI_API_KEY

Python

This gets the coupon details and prints the headline, expiry date, and claim steps, using the official SerpApi Python library:

Install the library:

pip install serpapi
import os
import serpapi

client = serpapi.Client(api_key=os.environ["SERPAPI_API_KEY"])

results = client.search({
    "engine": "amazon_promotion",
    "promotion_id": "ASV27IGU190N",
})

promotion = results.get("promotion_results", {})

print(promotion.get("title"))
print(promotion.get("expiration"))
for step in promotion.get("how_to_claim", []):
    print(f"- {step}")

Output:

Save 25% on your Subscribe & Save subscription
Coupon Expiry Date January 1, 2027
- Select the Clip Coupon button.
- Add 1 item from the products below to your Cart using the Add to Cart button or select See Options for specific product variations.
- When you're done shopping, select Go to Cart.
- The offer will automatically be applied at checkout, if eligible.

JavaScript and Node.js

This runs the same request with the SerpApi JavaScript library. Install it:

npm install serpapi

Create a new file index.js

import { getJson } from "serpapi";

const results = await getJson({
  engine: "amazon_promotion",
  api_key: process.env.SERPAPI_API_KEY,
  promotion_id: "ASV27IGU190N",
});

const promotion = results.promotion_results ?? {};

console.log(promotion.title);
console.log(promotion.expiration);
for (const step of promotion.how_to_claim ?? []) {
  console.log(`- ${step}`);
}

cURL

This gets the coupon details straight from the command line:

curl --get https://serpapi.com/search \
 -d api_key="SERPAPI_API_KEY" \
 -d engine="amazon_promotion" \
 -d promotion_id="ASV27IGU190N"

Other languages and no-code solutions

Even if there's no official SerpApi integration for your language, you can use the API directly with GET requests and parse the JSON response. SerpApi also works with no-code tools like Make.com and n8n.

Get the products that qualify for a coupon

A coupon often covers dozens of products, and only some variants qualify. Add include_products=true to get the full list. This script reuses the client from above, prints each product, and saves them to qualifying_items.csv:

import os
import serpapi
import csv

client = serpapi.Client(api_key=os.environ["SERPAPI_API_KEY"])

PROMOTION_ID = "ASV27IGU190N"

results = client.search({
    "engine": "amazon_promotion",
    "promotion_id": PROMOTION_ID,
    "include_products": "true",
})

items = results.get("qualifying_items", [])

for item in items:
    print(f"{item.get('asin')} | {item.get('price')} | {item.get('title', '')[:60]}")

with open("qualifying_items.csv", "w", encoding="UTF-8", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["promotion_id", "asin", "title", "brand", "price", "rating", "reviews", "prime", "link"])
    for item in items:
        writer.writerow([
            PROMOTION_ID,
            item.get("asin"),
            item.get("title"),
            item.get("brand"),
            item.get("extracted_price"),
            item.get("rating"),
            item.get("reviews"),
            item.get("prime", False),
            item.get("link"),
        ])

print(f"Saved {len(items)} qualifying items to qualifying_items.csv")

if results.get("qualifying_items_truncated"):
   print("Note: this list is incomplete. Try again later with no_cache=true.")
elif not items:
   print("This promotion has no product list. It only shows terms.")

Output:

B0CDHNX333 | $19.49 | Orgain Organic Kids Dairy 8g Protein Shake, Fruity Cereal, 8
B00BYOW7VG | $21.21 | Orgain Organic Kids Dairy 8g Protein Shake, Vanilla, 8.25 oz,
...
Saved 95 qualifying items to qualifying_items.csv
Qualifying products exported to CSV

Three things to know about this list:

  • Not every coupon has a product list. Some coupons, often small ones such as "Apply $1 coupon", only have a terms page. For these, the response has no qualifying_items field, and the title is a generic View promotion details. The script prints a note when that happens.
  • qualifying_items_truncated is true when the list is incomplete, either because a very large promotion hit the safety cap or because Amazon didn't return the product grid. The second case can be temporary, so try the request again later with no_cache=true.
  • Prices are shelf prices. extracted_price is the price before the coupon. Use saving_info to calculate the discounted price.

Each item also has a serpapi_amazon_product_link. Call it to get the full product page, including variants, specifications, and reviews. For more on looking up products by ASIN, see our Amazon ASIN lookup guide.

Track Amazon coupons with Python

Coupons end early, run out, or get replaced. If you keep a list of promotion IDs, for example from your own brand, your competitors, or a deal feed, this script checks each one and records whether it's still active.

Here's what the script does:

  • Checks every promotion ID in PROMOTION_IDS, up to MAX_PROMOTIONS per run
  • Records the title, savings, and expiry date for active coupons
  • Marks a coupon as ended when the API says it has ended or wasn't found
  • Stops with an error for anything else, such as an invalid API key, so a bad key isn't recorded as an ended coupon
  • Saves the results to coupon_status.json with the date checked
import json
import os
from datetime import date

import serpapi

client = serpapi.Client(api_key=os.environ["SERPAPI_API_KEY"])

PROMOTION_IDS = [
    "ASV27IGU190N",
    "A1C1U2DDI9B2GB",
]
MAX_PROMOTIONS = 20  # each promotion uses one search
ENDED_MESSAGE = "Promotion has ended or was not found."

def check_promotion(promotion_id):
    try:
        results = client.search({
            "engine": "amazon_promotion",
            "promotion_id": promotion_id,
        })
        error = results.get("error")
    except serpapi.HTTPError as http_error:
        error = http_error.error

    if error == ENDED_MESSAGE:
        return {"promotion_id": promotion_id, "status": "ended"}
    if error:
        raise RuntimeError(f"{promotion_id}: {error}")  # e.g. invalid API key

    promotion = results.get("promotion_results", {})
    return {
        "promotion_id": promotion_id,
        "status": "active",
        "title": promotion.get("title"),
        "saving_info": promotion.get("saving_info"),
        "expiration": promotion.get("expiration"),
        "link": promotion.get("link"),
    }

report = {
    "checked_on": date.today().isoformat(),
    "promotions": [check_promotion(pid) for pid in PROMOTION_IDS[:MAX_PROMOTIONS]],
}

for promotion in report["promotions"]:
    print(f"{promotion['promotion_id']} | {promotion['status']} | {promotion.get('title', '')}")

with open("coupon_status.json", "w", encoding="UTF-8") as f:
    json.dump(report, f, indent=2)

active = sum(p["status"] == "active" for p in report["promotions"])
print(f"Checked {len(report['promotions'])} promotions, {active} active. Saved to coupon_status.json")

Output:

ASV27IGU190N | active | Save 25% on your Subscribe & Save subscription
A1C1U2DDI9B2GB | ended | 
Checked 2 promotions, 1 active. Saved to coupon_status.json
💡
MAX_PROMOTIONS caps the number of searches per run. Lower it while testing so you don't use up your monthly searches.

There are a few ways you can extend this script:

  • Run it on a schedule. Use cron or Task Scheduler to run it daily and compare each run with the last one.
  • Alert on changes. Send a message when a coupon ends or its saving_info changes.
  • Add the products. Set include_products to true to also track which products join or leave a promotion.

FAQ

Does Amazon have a coupon API?

Not a public one for coupon pages. Sellers can create and report on their own coupons in Seller Central, and affiliates get product and offer data through Amazon's Product Advertising API. Neither returns a public coupon page with its terms and qualifying products. This Amazon Promotion API fills that gap.

Where do I find an Amazon promotion ID?

In the coupon page URL. It's the code after /promotion/psp/ or /promotion/details/popup/, for example ASV27IGU190N.

Can I find every Amazon coupon with this API?

No. It returns one promotion per request, so you need the ID first. To spot products that have a coupon, use the Amazon Search API. Its organic results include a save_with_coupon field, such as Save 10% with coupon, but not the promotion ID.

What happens when a coupon ends?

The API returns an error: Promotion has ended or was not found. The tracking script above records these as ended.

Does it work on other Amazon marketplaces?

Yes. Set amazon_domain to the marketplace you need, such as amazon.co.uk or amazon.co.jp. Every supported Amazon domain works except amazon.cn.

Conclusion

The Amazon Promotion API turns any Amazon coupon page into structured JSON or Markdown, so you can check coupon terms, export qualifying products, and track which coupons are still active without maintaining your own scraper. You can then pair it with the Amazon Product API to get full details for each qualifying product, or use it alongside an Amazon price tracker to see the real price after a coupon.

If you need help getting started, contact us. We're happy to help.