For business partners
Developers
Show your customers Canopy's independent lab results for your products, right on your own website.
Overview
The Canopy results widget is an embeddable iframe that displays the latest published test results for one product — the same lab data, detected-contaminant summary, and interactive results chart shown on Canopy, in a compact frame sized for product pages.
The widget is available to Canopy business partners. Not a partner yet? Get in touch through our services page.
Authentication
Every embed request is authenticated with your API key, generated from the API keys section of your account. Keys look like cnpy_… and are shown exactly once when generated — store yours somewhere safe. If you lose it (or need to invalidate it), rotate it from your account: the old key stops working immediately and you get a new one.
The key identifies your account and meters requests. It only grants access to published, public test results — never to account data.
Embed reference
Point an iframe at https://www.forcanopy.com/embed with two query parameters:
| Parameter | Required | Description |
|---|---|---|
| key | Yes | Your partner API key. |
| upc | Yes | The product's UPC barcode, as printed on the package. |
The widget always shows the product's latest published test (by lab sampling date). If the product has been re-tested, older lots aren't shown — the full history remains on the product's Canopy page, which the widget links to.
The frame always renders a friendly card — an invalid or disabled key, or a product without published results, shows an explanatory message rather than a broken frame.
Live example
A real product rendered by the widget. Your embed looks the same, scoped to the UPC you pass.
Embed code
<iframe
id="canopy-embed"
src="https://www.forcanopy.com/embed?key=YOUR_API_KEY&upc=PRODUCT_UPC"
width="100%"
height="600"
style="border:0"
title="Canopy test results"
></iframe>
<script>
window.addEventListener("message", (event) => {
if (
event.origin === "https://www.forcanopy.com" &&
event.data && event.data.type === "canopy-embed-height"
) {
document.getElementById("canopy-embed").height = event.data.height;
}
});
</script>The widget reports its content height to your page, and the snippet's script resizes the iframe to match — so the embed always shows at 100% of its content height with no inner scrollbar. Omit the script and the frame keeps its fixed height, scrolling internally.
Customizing
The widget ships in Canopy's house style, but four query parameters let it match your site: colors, titleFont, bodyFont, and logoTheme. All are optional, combine freely, and invalid values simply fall back to the default look — never a broken frame.
Logo theme
The Canopy wordmark in the "Powered by" footer is an image, so it's the one part of the widget your color overrides can't restyle. If your colors give the widget a dark background, add logoTheme=dark to use the light-on-dark logo. The default is the standard logo for light backgrounds.
https://www.forcanopy.com/embed?key=YOUR_API_KEY&upc=PRODUCT_UPC&logoTheme=dark
Typography
Titles and body text are styled independently. Set titleFont (headings) and/or bodyFont (everything else) to any Google Fonts family name. URL-encode spaces (e.g. titleFont=Playfair%20Display). Omit either to keep Canopy's default for that slot — serif headings, sans body.
https://www.forcanopy.com/embed?key=YOUR_API_KEY&upc=PRODUCT_UPC &titleFont=Playfair%20Display&bodyFont=Inter
Colors
Pass colors as URL-encoded JSON mapping Canopy's design-system tokens to hex values. Only the tokens below are recognized (hex colors only); the diagram shows where each one appears in the widget.
| Token | Default | Used for |
|---|---|---|
| background | #F8FAFF | Page and card fill |
| onbackground | #101D46 | All text, chart axis labels |
| surface | #E9EFFF | Soft panels and hover fills |
| surface2 | #C6D4F9 | Card and table borders |
| cta | #101D46 | Chart bars, in-widget links |
| onCta | #F8FAFF | Text on cta-colored elements |
| ctaNegative | #DC3D43 | Detected-pill text |
| surfaceNegative | #FFEFEF | Detected-pill fill |
backgroundProduct name, headings, all text
onbackgroundsurface2surfaceNegativefill ·ctaNegativetextsurfacectaRegulatory reference lines keep their fixed data-viz palette (chosen for distinguishability) and are not customizable.
https://www.forcanopy.com/embed?key=YOUR_API_KEY&upc=PRODUCT_UPC &colors=%7B%22background%22%3A%22%23FFFFFF%22%2C%22cta%22%3A%22%230F766E%22%7D
Playground
The preview uses the demo product and starts from the widget's standard palette — edit any value to see it change. LeavetitleFont/bodyFontempty for Canopy's default typography. Pass the samelogoTheme/titleFont/bodyFont/colorsparameters on your own embed URL.
Try it
Requests made here count against your key's usage.