September 11, 2026 — the $2,000 plan is renamed Scale, and publishing no longer requires a plan
The $2,000-a-month plan is now called Scale. Separately, a storefront no longer needs a plan to go live: publishing has been open to every store since September 1, 2026.Changed
  • Enterprise is now Scale. Same plan, same $2,000 a month per store, same card rate (3.4% + 30¢ on domestic cards). Only the name changed. Earlier entries in this changelog that mention the Enterprise plan mean this plan.
  • Publishing no longer requires a plan (since September 1, 2026). This reverses Build free, pay to publish from v1.13. Once an account’s email address is confirmed, its store’s default theme goes live on its PlatformDTC address, and every later publish goes through without a plan check.
Unchanged
  • Prices and billing. Basic $20, Pro $200 and Scale $2,000 a month per store, billed monthly. The $1 first month still applies once per account, to the first plan you start. There is still no free plan and no free trial.
  • Subscriptions on the $2,000 plan. They are not moved, repriced or re-billed. The plan’s identifier is still enterprise; only its displayed name changed.
  • The one-time $100,000 AI credit is still granted when a new account confirms its email.
  • Storefronts that are already live stay live.
Orders is one screen — Disputes and Drafts are tabs of the order list, and every tab shows its count the same way
Disputes and Drafts are no longer separate screens. They are tabs in the same row as All Orders, Open, Fulfilled, Cancelled, Alert and Warning, with the same toolbar and table.The row is grouped: order status (All Orders, Open, Fulfilled, Cancelled) | fraud signals (Alert, Warning) | Drafts and Disputes.Changed
  • Disputes is a filter of the order list. It shows the orders a cardholder has disputed, in the same table as every other tab. Each row carries a dispute badge — for example Chargeback · Under review — and hovering it shows the reason and when evidence is due. Open a row for the full dispute.
  • Respond to disputes automatically now sits in the toolbar while the Disputes tab is open.
  • Drafts use the order list’s toolbar and table. Search drafts by number (with or without the #) or by customer email, filter them by Open, Invoice sent or Completed under Filters, and create a draft from the toolbar.
  • Every tab shows its count in the same style, including Alert, Warning, Disputes and Drafts.
Fixed
  • Exporting from the Alert, Warning or Disputes tab now exports exactly the orders on that tab. It used to export every order.
Old links to the Disputes and Drafts screens, including the link in dispute notification emails, open the matching tab.
Every action on the order page now works — returns, printing, duplicate, notes, tags and messaging
The order page’s actions are all live. Controls that looked clickable but did nothing now either do the job or are gone.New
  • Return on fulfilled orders — pick the items, quantity, reason and restock option; quantities are capped at what is not already on a return. Manage the return from Returns.
  • Print → Order invoice and Print → Packing slip, printed straight from the browser.
  • Duplicate creates a draft order with the same items, customer and ship-to.
  • Notes and Tags are editable from the order page.
  • Message customer opens a support email to the buyer, addressed and titled with the order number.
Fixed
  • An item’s name now opens that product in your catalog.
  • The customer’s name opens their customer profile.
  • Refund at the top of the page opens the refund form, and appears only while money is left to refund.
  • Cancel order asks you to confirm, with an optional reason, instead of cancelling on the first click.
  • The status beside the order number is the real payment status. A refunded order no longer reads “Unpaid”.
  • The order page and its printed documents show your store’s order number (for example #603), the same number as the orders list and return names, instead of a 36-character id.
  • The billing address is shown only when checkout recorded one. “Same as shipping address” appears only when the two match.
Removed
  • Edit and Mark as delivered, which had nothing behind them.
See Manage an order.
Dispute, payout and account fees at cost — itemised in Finance and deducted from your balance
PlatformDTC pays the payment processor’s dispute, payout and account fees for your store. From September 11, 2026 they are recovered at cost, itemised in your dashboard, and deducted from your PlatformDTC Payments balance.These fees were always charged — to PlatformDTC, on your store’s behalf — but they never appeared anywhere you could see them. They now have their own statement, every line at the processor’s own price with no margin, and they are taken from the balance your sales build rather than added to an invoice a month later.Changed
  • Dispute fees, at cost. $15 for every dispute received, which the card network charges whatever the outcome, and a further $15 when a dispute is contested — credited back to you if you win. This replaces the $20 chargeback fee.
  • Payout and account fees, at cost. 0.25% + 25¢ of each payout sent to your bank, and $2 for each month in which your account receives a payout.
  • Collected from your balance, not your invoice. These fees, and any international or currency-conversion cost that could not be taken inside a payment (the v1.16 shortfall), are deducted from your PlatformDTC Payments balance. A deduction never takes your balance below zero; anything it cannot cover yet is retried when funds arrive.
New
  • Platform fees on Finance → Payouts. An itemised statement of every amount — what it was for, the period, the amount, and whether it is owed, being collected, collected or credited — and every deduction made from your balance.
Past periods
  • Costs PlatformDTC paid for your store before these terms took effect are recoverable at cost: international and currency-conversion costs not taken in a payment’s fee before 09:00 UTC on September 11, 2026, payments charged below your current plan’s rate, and dispute, payout and account fees. Each is itemised on Finance → Payouts, and nothing for a past period is deducted until at least 14 days after we email you notice.
Unchanged
  • Your card rate — 3.8% + 30¢ on Basic, 3.5% + 30¢ on Pro, 3.4% + 30¢ on Enterprise — and the at-cost international (+1.5%) and currency-conversion (+1%) pass-through from v1.16.
  • No margin on any pass-through, and still no separate transaction fee.
  • A rate card agreed in writing for your store still applies.
The full terms are in sections 6.2.2 to 6.2.5 of the Terms of Service; every rate is on platformdtc.com/pricing.
International and currency-conversion costs are now taken in each payment's fee
From 09:00 UTC on September 11, 2026, the card costs that depend on where a card was issued are priced into the payment itself.Your plan’s card rate has always been the rate for a domestic card. A card issued in another country, or an order charged in a currency other than your account’s, costs more to process — and until now that difference was not visible on the payment it belonged to. It is now taken in that payment’s transaction fee, at the moment of the charge, at cost.Changed
  • International cards: +1.5%, at cost. When a card was issued outside your payments account’s country, 1.5% of the payment is added to that payment’s fee. Cards issued in Puerto Rico and other US territories count as US cards.
  • Currency conversion: +1%, at cost. When an order is charged in a currency other than your account’s default currency, 1% of the payment is added to its fee.
  • Renewals and post-purchase offers are priced off the saved card, the same way.
  • Klarna and Afterpay carry their own processing rate. 5.99% + 30¢ for Klarna and 6% + 30¢ for Afterpay, plus your plan’s commission — 6.89% / 6.59% / 6.49% + 30¢ for Klarna and 6.9% / 6.6% / 6.5% + 30¢ for Afterpay on Basic / Pro / Enterprise.
  • What could not be priced at the charge goes on your next invoice. If a card’s issuing country was not available when the payment was made, the amount not collected appears as an itemised line on your next PlatformDTC invoice, with the number of payments, the volume and the rate.
Unchanged
  • Your domestic card rate. 3.8% + 30¢ on Basic, 3.5% + 30¢ on Pro, 3.4% + 30¢ on Enterprise.
  • No margin on either pass-through, and still no separate transaction fee.
  • Nothing charged before 09:00 UTC on September 11, 2026 is repriced or billed.
  • A rate card agreed in writing for your store still applies.
The full terms are in section 6.2 of the Terms of Service; every rate is on platformdtc.com/pricing.
Support shows the photos your customers send, and lets you send them back
Attachments arrived in the support inbox — in both directions.Customers have always been able to attach things to the emails they send you. Until today the inbox threw all of it away: the text of the message came through, and the photo of the crushed parcel, the screenshot of the order confirmation and the PDF invoice did not. A thread would say “photo attached” and there would be no photo, so answering it meant leaving the dashboard and opening the mailbox in another client. Replies had the same hole in the other direction — there was no way to send a shipping label or a replacement receipt from the reply box.New
  • Files a customer sends now appear in the thread. Pictures are shown at full width, and every file — image, PDF, spreadsheet, anything — is listed under the message with its name and size, one click to download. Click a picture to open it full-screen.
  • Attach files to a reply. A paperclip under the reply box, or drag files onto it, or paste a screenshot straight in. Images you attach are embedded in the email your customer receives, so they see the picture in the message rather than having to open an attachment.
  • Attach files when you write first, too. The same on New email.
  • A reply can be nothing but a file. “Here is your label” with the label attached and no words is a real answer, and Send now allows it.
  • Up to 20 files per message, 25 MB each — the same ceiling email itself has.
Unchanged
  • Nothing about how mail reaches you or leaves you. Same mailbox, same address, same threading.
  • Your customers’ files stay private. They are not on a public link. Only someone signed in to your store can open them, and every attachment is checked against its own fingerprint before it is handed over.
Your dashboard now says when your store has no way to pay you
A store with no payment account is told so, on every page, until it has one.A store is created without a payment account, and until today nothing in the product said that out loud. The storefront looked finished, orders could arrive, and the one setup step between having a store and being paid for it was a settings page nobody had a reason to open. Payments activation is now a first-class notice: it appears in the notification bell, and — while your store still has no way to be paid — as a banner across the dashboard.Changed
  • A payments notice on every dashboard page. It carries the reason it is there and a single button to Settings → PlatformDTC Payments. Once payments are set up it disappears on its own; there is nothing to acknowledge.
  • What it says depends on your store. If orders are already arriving and there is no payment account, the notice says how many, and it cannot be dismissed — money is being taken with nowhere to send it, and that is not something to hide behind a close button. If you have not sold yet, it is the ordinary setup nudge and closes for the day. If you run your own card processor, it is an offer rather than a warning, and it stays in the bell rather than taking a banner.
  • One thing at a time on a new account. While your confirmation email is still outstanding — the thing holding your storefront offline — the payments nudge waits its turn rather than stacking a second banner on the first.
  • Dismissing it anywhere dismisses it everywhere. The banner and the bell are the same notice, so closing one no longer leaves the other showing a badge for the same sentence.
  • Payment notices no longer name our processor. Every message about the PlatformDTC Payments rail now calls it PlatformDTC Payments, matching the order timeline and the payments settings page. Your own connected Stripe account is still called Stripe Card, because that is what it is.
Unchanged
  • Nothing about how you set payments up. Same page, same verification, same account.
  • Stores that already have payments set up see nothing new. The notice only exists while there is no payment account, and it is per store, not per account.
Public beta — sign-up is open to anyone
Anyone can now create an account and build a real store.Until today the way in was a conversation. Sign-up is open: you register, and at the end of it there is a real store on a subdomain with a default theme already seeded and ready to edit — no sales call, no invite code, no waitlist, nothing to wait for. Building it costs nothing; the storefront starts serving shoppers when you start a plan. Nothing about existing stores changes; this is a door being added, not a door being moved.Public beta is a statement about pace, not about quality. These are not sandboxes — a published store is a real store taking real payments. What it means is that behaviour we think is wrong gets fixed rather than preserved for compatibility, and that when a change is the kind a merchant would notice, it lands here first.Changed
  • Sign-up is self-serve. Register at platformdtc.com/register and the store exists when you finish, seeded and ready to edit.
  • Build free, pay to publish. The theme editor, catalog, checkout settings and the rest of the dashboard are open on the real product from the moment you register — not a demo of it. Serving shoppers is what a plan buys: until one starts, the storefront is not published.
  • Plans are priced per store, and the first month is $1. Basic $20/mo, Pro $200/mo, Enterprise $2,000/mo; each plan covers one store, so a second store is a second plan. The $1 first month applies once per account, to the first plan you start. There is no Free plan. Card processing is billed separately at 3.8% + 30¢ on Basic, 3.5% + 30¢ on Pro and 3.4% + 30¢ on Enterprise.
  • New accounts get a one-time grant of $100,000 in AI credits. The agent surface is the part worth trying, and it is metered — the grant is there so trying it is not a budget decision.
  • A page explaining what beta means for you. Public beta sets out what is covered, what may change under you, how to report something broken, and where to check whether it is us or you.
Kept working
  • Storefronts that are already live stay live. Pay-to-publish is a rule for stores that have not been published yet. Nothing that was already serving shoppers went dark, and nothing needs to be re-published to stay up.
  • Merchants already on a plan keep the price they are on. The catalogue above applies to plans started from today. Retired plans are deactivated, not deleted: a subscription still on one keeps its own price and its own card rate.
  • Nothing else changed for existing stores. Same dashboard, same API, same keys, same scopes. No migration, no re-authentication, no plan change.
  • Talk to sales is still the front door. If you are migrating a catalog or moving live subscriptions, that path is unchanged and is still the one we would point you at. Self-serve is an addition to it.
  • The Gateway contract is unchanged. Scopes, idempotency, jobs, approvals and webhooks behave exactly as documented. Opening sign-up did not loosen any gate.
Status for the surfaces we probe — storefronts, checkout, dashboard, Core API, notifications and these docs — with p50/p95 per component: status.platformdtc.com.
Checkout now runs on platformdtc.com
Your checkout has moved off a separate address and onto the main one.Shoppers used to be handed from your store to checkout.platformdtc.com — a hostname that matched neither your brand nor anything they had clicked. That hop cost a fresh DNS lookup and TLS handshake on the slowest possible moment in the funnel, and it showed buyers a domain name nobody chose. Checkout now runs at platformdtc.com/checkout/… instead, on the same address as everything else.Stores on their own custom domain are unaffected and remain the better setup: checkout there runs on yourbrand.com, where the shopper never leaves your brand at all.Changed
  • Checkout runs at platformdtc.com/checkout/<session>. One origin, one certificate, one connection — the checkout page now reuses the connection the shopper already has.
  • Buy-now permalinks read platformdtc.com/cart/<variant>:<qty>. The permalink keeps the same shape it has always had; only the domain changed. A permalink is the one checkout link a person reads and pastes, so its shape does not move when your store does.
  • Express wallets registered on the new address. Apple Pay, Google Pay, Link, Amazon Pay and Klarna are registered for the new host before any store is moved onto it. They only render on a registered hostname, and an unregistered one fails silently — so the move is gated on the registration, not on a checklist.
Kept working
  • Every link you have already sent still resolves. Permalinks running in live ad campaigns, recovery emails already in inboxes and links inside released mobile app builds keep working. They are forwarded to the new address with their query string intact, so payment returns and campaign attribution are unaffected.
  • Your shopper account area has not moved. Sign-in, orders, saved products, followed stores and the subscription portal stay exactly where they were.
  • Nothing about your checkout changed but the address. Same branding, same blocks, same payment providers, same settings.
New reference: Checkout URLs.
Removing a domain now frees its email too
A domain you remove is now genuinely free — including the email on it.Removing a custom domain used to release only half of it. If you had set email up on that domain, the mail side kept holding the name: one domain belongs to one account, permanently, because two accounts sharing a mail domain would be two accounts able to read each other’s mail. So the domain looked disconnected, and setting it up on another store answered “that domain is already served by another organisation” — with nothing you could do about it from your own dashboard.Added
  • Remove email from a domain. In Settings → Domains → Email from your domain, each configured domain now has a remove action. It asks first, and it says what goes: a sending domain stops sending as your address and falls back to [email protected]; a full-mailbox domain loses its mailboxes and the mail in them.
  • Removing the domain removes its email too. Disconnecting a custom domain now releases the matching mail setup automatically, so the name is immediately usable on another store or another account.
  • A confirmation before a domain is removed. Removing a domain was one unconfirmed click. It now asks, and when the domain carries your email it says so in the dialog, before anything is torn down.
Kept safe
  • Your other addresses are untouched. Email lives on the root domain, so if you have both brand.com and shop.brand.com connected, removing one of them leaves the email alone — it is only released when the last hostname on that domain goes.
  • Nothing is released while it might still be receiving. If the mail service cannot be reached, the removal reports a failure and changes nothing rather than freeing a name whose mailboxes are still live.
Every parcel tracked, and told to you when it stops moving
Your store now watches all 3,393 parcels it has shipped, not a sample of them — and emails you when a batch of them stops moving.Until now only the most recent shipments were registered with the carrier aggregator, because registration is metered and the backfill ran a seven-day window. That meant most tracking numbers had no scan data behind them: a shopper pasting theirs into your tracking page was told the order could not be found, which is the worst possible answer to give someone who is already anxious about a parcel.Added
  • Full tracking coverage. Every fulfilled order carrying a tracking number is now registered and syncing, so your tracking page answers for all of them.
  • Delivery alerts. One email per issue per day — never one per parcel — when enough of your shipments cross a line: the carrier has flagged them (held, returning, failed delivery), they have been silent for over a week, they are past the delivery date you promised, or they were marked shipped and never scanned at all. Each email says what the number means, names a few of the parcels, and links straight to them.
  • “Preparing to ship” now means what it says. Carriers report a printed label the same way they report a real shipment, and we were passing that through as Shipped — on 266 parcels, 109 of which had been sitting that way for over a week. Those now read “Preparing to ship” for your shopper, and get their own line on the delivery dashboard so you can see which supplier printed labels and dispatched nothing. Transit times were also being measured from the moment the label was printed rather than the first real carrier scan; they are now measured properly, which is why your average may have moved.
  • A reason for every hidden scan. The tracking page has always suppressed origin-country and non-English carrier lines so your brand story does not end on a foreign logistics portal. Now each hidden scan records which rule hid it, so the policy can be audited instead of trusted.
What Meta claims, and what the data can stand behind
A new report at Analytics → Advertising. It puts Meta’s reported ROAS beside a number built only from orders we can prove came from a Facebook ad click, and explains the difference.Ad platforms report their own contribution, and every platform takes full credit for every conversion it touched. Meta’s default counts a purchase up to seven days after a click and one day after a mere view, and fills the gaps it cannot observe with modelled estimates. On one live store over thirty days, Meta claimed more conversion value than the store took in revenue — including subscription renewals no advertisement drove.Added
  • The claim beside the floor. Meta’s ROAS and a click-only ROAS over the same spend. The second is deliberately conservative: it counts only orders carrying a real Facebook click identifier, so the true figure sits between the two.
  • Where the gap comes from, as arithmetic against your own books — how many more conversions Meta claims than you had orders, and what share of your total revenue its claim represents.
  • What the evidence supports, tier by tier, with unattributed revenue shown at full size as its own line. We never spread unknown revenue across channels; that is what makes a platform number look better than it is.
  • A per-campaign table, Meta’s claim next to ours. Campaigns we cannot measure show a dash and an unmatched badge — not a zero. “We could not measure this” and “this sold nothing” are different statements, and only one of them is true.
  • Coverage, stated plainly. Every figure carries the share of orders and spend it rests on.
Notes
  • Campaign-level figures depend on an ad’s destination naming the product it sells. Ads landing on a product page, or on a product-named domain, are matched automatically; the rest are reported as unmatched rather than guessed at.
  • Subscription renewals inherit the attribution of the order that acquired them. Renewals whose acquisition predates click-id capture stay unattributed, and the report says so instead of showing a zero.
Disputes answer themselves
Chargebacks can now be contested automatically. Turn it on at Orders → Disputes, on the switch above the table.A card dispute gives you roughly seven days to respond, and a deadline that passes in silence is scored as a loss — the money, the goods, and a mark against the dispute rate that card networks cap. Until now PlatformDTC could show you a chargeback but not answer one; answering meant logging into your payment provider before a deadline nobody was watching.Added
  • Automatic evidence submission, per store, off by default. When on, we build the response from the order’s own records — customer name and email, the IP the order was placed from, billing and shipping address, carrier and every tracking number on the order (including each leg of a split shipment), the line items, and your published refund policy — and submit it to the cardholder’s bank.
  • Timed to the deadline, not to the filing. Evidence goes about 48 hours before the deadline, because it can only be sent once: a delivery scan that lands on day five belongs in the response.
  • Reason-aware. A non-receipt dispute leads with delivery proof, a duplicate-charge dispute explains the difference between the two charges, and a cancelled-subscription dispute answers the cancellation claim.
  • An Evidence column on the disputes table — submitted (with the timestamp), queued, retrying, not contested, or deadline passed.
  • An alert when we answer for you, listing exactly which evidence fields were sent, and a matching entry on the order’s own timeline.
What it will not do
  • It never contests a refunded order. If you already refunded, the money is back with the cardholder; those are marked not contested and left alone.
  • It never fabricates. A fact the order cannot substantiate is left out rather than guessed — an issuer weighs a contradicted claim against you.
  • It does not cover PayPal disputes, which have their own evidence process.
Note. Evidence can be submitted to a bank exactly once and cannot be edited afterwards. Turning this on delegates that one response for every future dispute; the exact payload we sent is kept on the dispute so you can always see what was argued.
Traffic & Behaviour report
Analytics has a sixth report, and it is the first one that is not about orders. Open it at Analytics → Reports → Traffic & Behaviour.Every report until now answered a question about a purchase. This one answers the question underneath it: of everyone who arrived, how many got anywhere, and what stopped the rest. The on-site pixel has been recording that since it shipped — scroll depth, engaged time, rage and dead clicks, form abandonment, script errors, Core Web Vitals — and until now nothing read it back.Added
  • Traffic — sessions, visitors, pageviews, pages per session, bounce rate and returning-visit share.
  • Engagement — average engaged time (which accrues only while the tab is visible and the visitor is actually doing something, so a tab left open all afternoon counts for nothing), scroll depth, how many readers reached the bottom of the page, and what share of sessions reached a checkout step.
  • Friction — rage clicks, dead clicks, the share of sessions that hit a script error, frustrated sessions, and form abandonment. This is the part of the report that tells you where orders are being lost rather than that they were.
  • Site Speed — Largest Contentful Paint, Interaction to Next Paint, Cumulative Layout Shift and Time to First Byte, each at the 75th percentile, measured on your real visitors’ devices rather than in a lab.
  • Same date filter and same previous-period comparison as every other report, so the numbers here line up with the ones next to them.
Changed
  • A metric where a rise is bad now says so, and the dashboard colours it accordingly. Refunds, Returns, Disputes, Unsubscribes, Cancellations and Churn were all painted green when they grew. They are not.
Note on the numbers. Every tile in this report is marked best-effort. On-site telemetry is deliberately dropped rather than allowed to slow a page down, so these figures are right for spotting a change and wrong for reconciling against orders — use the Sales and Profit reports for anything that has to balance.
Primary domain and redirects
A store now has one primary domain, and every other domain either redirects to it or serves the storefront on its own address. See Domains.Until now every domain attached to a store served the same storefront. A merchant with four domains had four copies of their store competing with each other in search, and no way to say which one was real.Added
  • traffic_mode on every domainprimary, redirect or serve. Redirects are 301 by default, preserve the path and query, and are answered at the edge before any request reaches the storefront.
  • GET /domains, PATCH /domains/{id}, PATCH /domains/{id}/set-primary on the Agent Gateway, so an agent can read and change a store’s routing under store:read / store:publish.
  • redirect_others on set-primary — fold every other attached domain into the new primary in one call, for a store that has drifted into several copies of itself.
  • A canonical URL on the storefront. The compiled storefront now emits <link rel="canonical"> and og:url built from the primary domain. Neither existed before: social previews and search engines were pointed at the platform subdomain even for merchants on their own domain.
  • The domains screen in Settings shows what each domain actually does — “Primary”, “Redirects to acme.com”, “Serving separately” — and flags when several domains are serving duplicate copies of the store.
Changed
  • Newly attached domains default to redirecting to the primary, matching what merchants expect. Domains attached before this release keep serving and are not touched — nothing started redirecting on its own. Change them when you want to.
  • A store’s first verified domain is promoted to primary automatically, so links and emails stop pointing at the platform subdomain the moment a domain goes live.
  • www and its apex are always treated as one address: promoting either one makes the other redirect to it.
Fixed
  • Meta CAPI event_source_url was resolved from a database table that does not exist, silently falling back to a legacy field. Purchase and subscription-renewal events sent from the server could therefore report the wrong store address, which degrades Meta’s event matching. Every URL the platform generates now comes from one resolver.
Public status page
status.platformdtc.com is live. Live operational state for the surfaces we probe, a rolling uptime record, and the full incident history — with email, Slack, Teams, webhook, RSS and Atom subscriptions. See Platform Status.Added
  • Eight components, grouped by who feels the failure: Storefronts and Checkout (buyer-facing), Merchant Dashboard and Core API (merchant), and Notifications, Background Jobs & Fulfillment, Analytics & Reporting and Documentation (platform).
  • A JSON API implementing the Atlassian Statuspage v2 contract/api/v2/summary.json, status.json, components.json, incidents.json, incidents/unresolved.json. Unauthenticated, CORS-open, cached 30s. Any existing Statuspage widget or uptime aggregator works against it with no adapter.
  • Response times, not just up/down. Every component publishes its p50, p95 and the tail ratio between them, alongside the exact thresholds we alert on. If you think a surface is slow you can cite the same number we do.
  • GET /api/v2/uptime.json — 90-day daily uptime history. A PlatformDTC extension; Statuspage keeps this private.
  • Signed webhooks using the same X-PlatformDTC-Signature HMAC-SHA256 scheme as platform webhooks, so existing verification code works unchanged.
Notes
  • The page has no origin server. It runs entirely on Cloudflare’s edge and shares no infrastructure with the systems it reports on, and its checks run from outside our network. A status page hosted on the thing it monitors goes dark exactly when you need it, so this one is verified the hard way: by cutting off every monitored service and confirming the page still loads and correctly reports a major outage.
  • Alerting keys on the tail, not the average. An internal investigation found individual API requests reaching 9.9s while the median held at a healthy 0.31s — every average-based dashboard was green for weeks. Thresholds are per-component because healthy baselines span two orders of magnitude across these surfaces, from ~12ms on cached checkout to ~1s on the server-rendered dashboard.
  • Feeds and webhooks emit one entry per incident update, not per incident, so subscribers hear about progress and resolution rather than only the opening.
  • Email is double opt-in. An unconfirmed address is never sent anything.
  • Individual stores are not modelled. Problems affecting a small number of specific stores may not appear — this reports platform-wide state. If your store is affected while the page is green, contact support rather than assuming it is you.
Import a product from a Shopify link
Import a product from its Shopify URL. Paste a link from any public Shopify storefront and get a real product in your store — title, sanitized description, images, options, and every variant with its own price, compare-at price and SKU. In the dashboard: My Products → Import Products → From a Shopify link.Added
  • POST /products/import/shopify/preview — reads the source store and returns exactly what would be created, writing nothing. Use it to show a confirmation step.
  • POST /products/import/shopify — creates a product per URL, up to 20 per call. One bad link never aborts the batch (207 Multi-Status on a mixed result).
  • Re-import is idempotent. A link whose source product the store already holds comes back as skipped with the existing product_id instead of creating a duplicate.
  • Both endpoints take the write_products scope. Preview needs it too, since it performs outbound fetches on your behalf.
Notes
  • Images are re-hosted on your own CDN, not hotlinked from the source store, so an imported product does not lose its photos when that store edits them.
  • Descriptions are sanitized — scripts, iframes and event handlers are stripped from the source body_html before it is stored.
  • Money is copied verbatim in the source store’s currency; no conversion is applied.
  • Inventory is not imported. Public storefronts expose whether a variant is in stock but never the count, so imported variants start untracked rather than with a made-up number.
  • Imports default to draft status so nothing reaches your storefront before you have reviewed the pricing.
  • Some storefronts block automated reads entirely. Those links report that plainly rather than failing silently or importing a partial product.
Products on the agent surface
Products is now a first-class agent API — the last core commerce object to reach the agent surface. /api/v1/products accepts X-Agent-Key: sq_agt_* alongside the dashboard’s user JWT, with the same audit log and Idempotency-Key semantics as the other resource APIs.Added
  • Full product surface — list (paged, searchable, sortable), get, create, partial update, soft delete, facets, duplicate, images, variants, bulk status/tags/delete, and the dropship catalog-link bind (POST/DELETE, previously read-only).
  • Writable fulfillment routingsupplier_id and fulfillment_rules are now settable through the API, so destination-based routing finally has a population path.
  • read_products / write_products scopes, matching the Shopify-parity naming the other resource APIs use.
Fixed
  • Commerce scopes were unmintable. read_inventory, write_inventory, read_discounts, write_discounts, read_gift_cards, write_gift_cards, read_metafields, write_metafields, read_returns, write_returns, read_draft_orders and write_draft_orders were enforced by the resource APIs but rejected at key creation, so no sq_agt_* key could hold them and those APIs were reachable only with a user JWT. All twelve are now grantable. Reissue any key that needs them — existing keys are unchanged.
  • offers:read / offers:write / offers:approve were unmintable too, for the same reason — and this was not theoretical: a key provisioned in production already carried all three and could never use them, because the scopes failed validation and the offers router was not mounted. All three are now grantable. offers:approve is deliberately not a spend scope — offer optimization gates its two dangerous calls in-band, at the call rather than the key.
  • write_gift_cards and write_discounts are now spend scopes. Both mint bearer value that is redeemable at checkout, so they belong behind the human-approval gate alongside ads:write and marketing:send.
Changed
  • catalog:read / catalog:write are now aliases of read_products / write_products. Already-issued keys keep working and either name authorizes either surface; no migration is required. New keys should use the *_products names.
  • GET /whoami gained an effective_scopes field. scopes continues to report the grant exactly as issued; effective_scopes shows it expanded through the aliases, so an agent debugging a 403 can see why a catalog:read key reaches a read_products route.
  • The tool catalog is generated from the MCP toolpack instead of hand-maintained. It had drifted to listing 23 of 78 tools.
Commerce resource APIs
Six new resource APIs are live under /api/v1, all on the scoped, idempotent, audited Agent Gateway:
  • Inventory & Locations — multi-location stock; set/adjust/move across quantity states.
  • Discounts — code & automatic discounts (DiscountNode model).
  • Gift Cards & Store Credit — issue/redeem gift cards, per-customer store credit.
  • Draft Orders — invoices/B2B/phone orders; calculate → invoice → complete.
  • Metafields — typed custom data on any resource + definitions.
  • Returns — RMA lifecycle + reverse logistics.
Plus platform hardening: a generalized Idempotency-Key middleware on every mutating group, reusable scope enforcement, and a centralized webhook topic catalog (products/*, inventory_levels/update, discounts/*, gift_cards/*, draft_orders/*, metafields/update, returns/*, refunds/disputes, GDPR compliance topics, bulk_operations/finish).
Fulfillment API
Supplier / 3PL fulfillment is live/api/v1/fulfillment. A Shopify-parity FulfillmentOrder API so third-party logistics and dropship suppliers can pull assigned orders, accept/reject, push tracking, and sync stock.Added
  • FulfillmentOrder model — orders split per assigned location; status × request_status state machine matching Shopify.
  • Supplier endpoints — register a fulfillment service (auto-provisions a location), /assigned_fulfillment_orders, accept/reject + cancellation handshake, create/update/cancel fulfillments (partials + multi-tracking), /inventory_levels/set & /adjust.
  • Scope enforcementread/write_assigned_fulfillment_orders, write_fulfillments.
  • Webhooksfulfillment_orders/*, fulfillments/*, orders/fulfilled + the fulfillment_order_notification service callback, HMAC-signed.
  • Auto-routing — paid-order line items routed to supplier locations by supplier id and auto-submitted so 3PLs are notified to ship immediately.
Agent Gateway
The Agent Gateway is live/api/v1/agent/v1. PlatformDTC is now agent-native.Added
  • 36 REST endpoints across store, catalog, ads, marketing, analytics, orders, jobs, and admin.
  • 23 dtc_* MCP tools via the mcp-platformdtc server for OpenClaw agents.
  • Service-account keys (sq_agt_*) with fine-grained scopes, per-key rate limits, rotation, and revocation.
  • Async job model with one poll surface (/jobs, /jobs/{id}, /jobs/{id}/wait).
  • Idempotency on all mutations.
  • Human-approval gate for spend actions.
  • Signed webhooks (HMAC-SHA256) for job.*, deploy.*, order.created, roas.threshold, approval.requested.
  • Full audit log of every call (/audit).
  • Interactive API playground + this documentation.
Roadmap
  • dtc_create_automation (multi-step workflow builder).
  • Endpoints: /analytics/daily-summary, /campaigns/{id}/analytics, /orders/import, job SSE streaming (/jobs/{id}/stream).