Build on the same rails our apps run on.
Two API surfaces: the Plunk Commerce Customer API brings your catalog intelligence into your own storefront or portal, and the Plunk Studio Shopper App API powers visualizer experiences: ours, or one your team builds.
Authentication & keys
API access is included with Studio Storefront and Plunk Commerce (see pricing). Plunk Commerce includes both the Customer API and the Shopper App API for the visualizer apps; Studio Storefront includes the Shopper App API. For now, request your keys from Plunk: talk to us and tell us which domains will call the API. There are two kinds of Customer API key; where a key may live is the security model, so it's enforced, not advisory.
| Key | Prefix | Lives in | Can do |
|---|---|---|---|
| Publishable | pk_live_… / pk_test_… |
Browser JavaScript on your website: shippable and public | Event ingest plus aggregate, non-PII reads (products, locations, recommendations). Origin-locked to your domains. Never returns revenue or personal data. |
| Secret | sk_live_… / sk_test_… |
Your server only, never a browser | Everything your account exposes, including revenue-bearing analytics and sales and order-status writes. Requests from browser origins are rejected. |
# Send the key as a bearer token (or X-Api-Key header)
curl https://api.plunk.io/cx/v1/capabilities \
-H "Authorization: Bearer pk_live_XXXXXXXXXXXX"
Test keys use live data. pk_test_ and
sk_test_ keys are labelled for testing but read and
write your real account; there is no sandbox. Use a separately named key while you
build, and don't post test sales or order status you don't want in your reports.
Web tracking & conversions
The tracker is one snippet on your site. Page views, sessions, geography, and campaign attribution are automatic from the moment it loads; conversions and engagements are one call each wherever something worth counting happens. Your account ID is in Plunk under Settings → Tracking, along with a copy-exact version of this snippet.
<!-- Paste in your shared footer, just before </body>, so it loads on every page --> <script> var plunkConfig = { appId: "YOUR_ACCOUNT_ID", accountId: "YOUR_ACCOUNT_ID" }; </script> <script src="https://s3.amazonaws.com/plunk.io/v4/js/plunk.tracker.io.js"></script> <!-- Optional, for conversions: keep a handle once the tracker is ready --> <script> document.addEventListener('plunk-tracker-ready', function () { window.plunkTracker = new Plunk.Tracker(window.plunkConfig); }); </script>
Conversions are the moments that matter: an order, a quote request,
a signup. value is money and flows into revenue
reporting, so set it when the moment has a price and leave it 0 when it doesn't.
// e.g. on your order confirmation page plunkTracker.sendConversion({ type: 'order', // your grouping: order, lead, signup… name: 'Order Placed', // how it reads in reporting identifier: 'INV-10442', // optional: order no, SKU, plan… value: 2450.00 // optional: dollars }, [ // the second argument is the identity & payload array { key: 'email', value: 'jamie@example.com' }, { key: 'phone', value: '555-201-4477' }, { key: 'order', value: JSON.stringify({ orderId: 'INV-10442' }) } ]);
That second array is how an event stops being anonymous. Include
email and/or phone
and Plunk creates or links the contact automatically. The event lands on
their timeline, and your lifecycle rules can promote them (a quote request
becomes a lead, an account approval becomes a prospect) or add them to a named
audience (every swatch requester lands in a "Fabric Orders" list, say) with no
extra calls. The event-to-audience mapping is account configuration, so
marketing can rename or retarget lists without touching site code. Any
other entries ride along as the event's payload. When you learn who a visitor is
outside an event, at a login for example, bind the session directly:
// binds this browser's history to the person from here on
plunkTracker.updateTrackingCookie({ email: 'jamie@example.com', phone: '' });
Engagements are the steps on the way: a configure button, a swatch order, a dealer-locator search. They cost nothing to record and they're what makes funnel drop-off visible between page view and conversion.
plunkTracker.sendEngagement({
type: 'cta', // your grouping
action: 'click',
label: 'request-quote' // which one, for the breakdown
}, []);
Page URL, session, visitor, and campaign are attached automatically to every call; you only supply what the event means. Events appear in your account's Activity reporting within a couple of minutes, which is also the fastest way to verify the install. Every type you send also becomes a building block elsewhere: funnel steps in Site Activity can match an event instead of a page path. That is the right choice for an order-placed step when your confirmation page is reached from an email link as often as from checkout.
Prefer not to hand-write the calls? Plunk generates a
per-account plunk-events.js under Settings →
Tracking: you declare the moments once, it emits one named function per event with
the identity plumbing above already wired. If the page already carries a GA4 tag,
the generated script can mirror every action into it: one call, both
systems, and email and phone go to Plunk only, never to GA4.
Plunk Commerce Customer API api.plunk.io/cx/v1
Versioned, key-scoped, and self-describing: your integration contract is the capabilities document. It lists exactly the resource families and endpoints your key can reach; new resources appear there as your account grows, so code against it rather than a static list.
/cx/v1/capabilitiesGET
The discovery document for your key: account type, enabled resource families, and the concrete endpoints inside each. Start here.
{
"tenantType": "retailer",
"families": [
{ "name": "products", "key": "publishable", "label": null,
"endpoints": ["GET /cx/v1/products/top/{range}", "…"] },
{ "name": "locations", "key": "publishable", "label": "Showroom",
"endpoints": ["GET /cx/v1/locations"] }
]
}
/cx/v1/products/top/{range}GET
Bestsellers for a period. range takes named tokens
(this_month, last_month,
this_year, …) or a custom window
(custom_20260101_20260630). Options:
?groupBy=product|category,
?category=, ?limit=.
Publishable keys receive rank, units and order counts; revenue fields appear on
secret keys only.
/cx/v1/locationsGET
Your stores or showrooms: the store-locator feed for your own site.
The full surface covers sales and order-status ingest, catalog sync and availability, recommendations, reviews, store and dealer analytics (including rep and dealer portals on your own site), audiences, contact interest, demand and restock forecasting, COM/COL requests, product images, and enrichment, and every family announces itself in your capabilities document.
Customer API referencePlunk Studio Shopper App API share.plunk.io
The COM/COL Visualizer, the Sectional Builder, and the Room Planner are apps we provide, and they run on a public, key-gated API your own team (or agency) can build against instead. A Visualizer App key from Studio scopes which apps it opens, locks website keys to your domains, and attributes every render and captured lead back to your account. Included with Studio Storefront and Plunk Commerce.
Drop-in embed (no code)
Website keys come with a copy-paste snippet: the fastest path to a visualizer on
your site. data-surface is
com, sectional, or
roomplanner.
<script src="https://share.plunk.io/embed.js"
data-key="YOUR_SITE_KEY" data-surface="sectional"></script>
Or build your own: the Sectional Builder API
Send your key on every call as x-visualizer-key.
Four endpoints make a complete shopper experience:
# 1 · Bootstrap: units, materials, options, and your account's policy GET /sb/bootstrap → { "brand", "builderMode": "open" | "curated", "units": [...], "fabrics": [...], "options": [...], "publishedConfigs": [...] } # 2 · Render: cache-first; a warmed combination returns instantly POST /sb/render { "units": [ { "sku": "L-2750-52", "gx": 0, "gy": 0 }, { "sku": "L-2750-53", "gx": 3, "gy": 0 } ], "fabricKey": "2001-05", "options": { "nailhead": "brass" } } → 200 { "status": "ready", "url": "…" } # cache hit → 202 { "status": "rendering", "renderId": "…" } # composing now # 3 · Poll until the composed hero lands GET /sb/render/{renderId} → { "status": "ready" | "rendering" | "pending_review" | "failed", "url" } # 4 · Save & share: mints a branded board, captures the lead POST /sb/save { "units": [...], "fabricKey": "2001-05", "title": "Living room L", "email": "shopper@example.com" } → { "configId", "boardUrl", "totalPrice" }
Every accepted render caches forever; a configuration renders at most once per material set, account-wide, then serves free and instant. In curated mode, shoppers see only the configurations your team has published; anything else returns a clean refusal rather than a render.
Studio API referenceWant a custom shopper app?
We also design and build custom consumer-facing visualizer, sectional-builder, and room-planning apps on these same APIs: your brand, your flow, our rendering and cache. Contact us and mention a custom app.
Integrations
Plunk connects to the systems you already run. No connector fees; everything below ships with the platform.
Commerce & catalog
Shopify syncs products, orders, and customers nightly, and approved Studio renders can publish straight back to your product pages. Prefer flat files? Scheduled CSV data feeds (products, sales, customers, inventory) cover any ERP or POS, and the Customer API accepts the same data programmatically.
Render delivery
Approved Studio renders deliver automatically to Shopify, Amazon S3, Azure Blob Storage, Dropbox, SFTP, or FTP: your site, your DAM, or your retail partners' inboxes, without a manual export step.
Marketing channels
Content publishes to Meta, Google Business Profile, WordPress, Mailchimp, and Constant Contact. Ad campaigns run across the major ad exchanges with server-side conversion events, so ROAS reflects real sales.
Use Plunk in your AI assistant
Your team can ask Plunk questions and get work done from Claude, ChatGPT, and other AI assistants: how a product line is selling, which accounts are slipping, what to restock, how a campaign performed. Each person signs in with their own Plunk account and sees only what that account can see. It starts read-only. This is for the people who use Plunk day to day, separate from the developer API above. Ask us to connect your account.