A respectful, evidenced read of the public surface
OSHAcademy did the genuinely hard, generous thing: every course is free to study, and the individual course and program pages are marked up with real Course and EducationalOccupationalProgram schema, better than most training providers. This is not a teardown. It's a short list of places where a finished learner, or a company certifying a crew, hits friction on the way to paying, each with the exact public proof, and each fixable without touching the training itself.
First: what's already strong (and rare)
"All training materials, knowledge checks and activities are free"; you only pay for the certificate/documentation. Most training providers gate the learning. This is a genuine strength; every finding below protects it.
Course pages carry Course schema with an offers array; program pages carry EducationalOccupationalProgram with the full hasCourse breakdown. That's ahead of the field.
The Shopify store ships full agent-commerce (UCP 2026-04-08 + MCP (Model Context Protocol) + Shop Pay). You adopted agentic checkout early; most brands haven't. Finding 1 is just about where it points.
HSTS preload, X-Frame-Options: SAMEORIGIN, X-Content-Type-Options: nosniff, CSP upgrade-insecure-requests, Sucuri WAF, IACET-accredited. Zero page errors on the home page.
Before the findings: the plain-English money
No jargon. Everywhere someone studies, OSHAcademy is already legible; these fixes are about the part people pay for, the certificate and the crew account. Here's what each is worth.
Your store is fully wired for hands-free AI purchase but stocked with shirts and water bottles, while the $16.99 certificate that earns the money routes to a legacy form, so an assistant told "get my crew the 30-hour certificate" can buy a mug but not the certificate.
The certificate's structured price sits a dollar or two below what the page actually charges, so an assistant quotes low and the buyer meets a higher number at checkout, a small trust break right where the money changes hands.
"Search OSHAcademy for confined-space courses" and "how do I certify my company" hit the two pages with no structured data, so your best, highest-value buyers arrive at a door that's blank to machines.
The highest-value buyer, certifying a whole team, ends at a "we'll contact you" form; a self-serve path lets that order complete the moment they're ready.
Four findings: where certificate revenue leaks
What happens. Your Shopify store, store.oshacademy.com, is fully wired for agent-driven purchase: it publishes a UCP merchant profile (version 2026-04-08), an MCP endpoint, and Shop Pay + Google Pay handlers. But its catalog is apparel, water bottles, mousepads, gifts, guides, and an audiobook ("Gear Up with OSHAcademy · Apparel + Accessories"). The certificate and program business, the actual revenue, lives on www.oshacademy.com, which publishes no agent-commerce profile, and routes the purchase to a legacy registration flow.
Why it costs certificate sales: a buyer's agent asked to "get the 30-hour construction certificate for my crew" can hands-free check out a $29 shirt today, but cannot buy a $16.99 certificate the same way. The agentic-commerce capability you already paid for is aimed at the low-margin catalog.
The proof
store.oshacademy.com/.well-known/ucp → ucp.version "2026-04-08", MCP endpoint /api/ucp/mcp, handlers: Shop Pay, Google Paystore.oshacademy.com/llms.txt → "This store implements the Universal Commerce Protocol… Search / Cart / Checkout"/collections/oshacademy-apparel, /gifts-for-safety-professionals, /guides-handbooks-and-audio-resources, no certificateswww.oshacademy.com/llms.txt · 404 www.oshacademy.com/sitemap.xml · no /.well-known/ucphref="../../student/register/step-1.php" (legacy)What happens. Your leaf pages are well-marked, but the two pages an agent uses to discover many courses or buy for a team are blank to machines. The 1,000-course catalog hub (/courses/list/course-catalog.html) renders with zero JSON-LD (the structured-data markup search engines and AI assistants read), and the business-account page renders with zero JSON-LD. Course and program pages also carry no Open Graph tags (og = 0), so link previews and AI cards fall back to guesses.
Why it costs certificate sales: "search OSHAcademy for confined-space courses" or "how do I certify my company" are exactly the high-intent, high-value queries, and they land on the two pages with no ItemList / Course / Offer or Organization / Service data to read. The doors that scale are the blind spots.
The proof: rendered-DOM JSON-LD counts (post-JavaScript)
105-hazard-communication-basic: ld+json = 1 (Course) · og = 030-hour-construction: ld+json = 1 (EducationalOccupationalProgram) · og = 0EducationalOrganization) · og = 9course-catalog.html: ld+json = 0 · og = 0What happens. Course 105's Course schema is present (good), but its offers prices don't match the live checkout. The schema lists PDF Certificate $15.99, Mailed $27.99, and "PDF & Mailed" $27.99, while the live page charges PDF $16.99 and PDF + Mailed (Best Value) $29.99. Every format's structured price is stale, and the schema prices the PDF+Mailed combo identically to mailed-only ($27.99), an internal data error. The visible prices are injected by JavaScript from a path your own robots.txt disallows (/programs/fees), so a non-JS crawler sees only a bare $.
Why it costs certificate sales: an assistant that trusts the schema quotes a price $1–$2 below the real one, a small surprise at checkout that erodes trust; an assistant reading raw HTML quotes no price at all. Either way the buyer's agent can't confidently commit.
// what the machine reads: Course schema Offer (105) // what the human pays: live, rendered "offers": [ { "name":"PDF Certificate", "price":"15.99" }, → PDF Certificate ............ $16.99 { "name":"Mailed Certificate", "price":"27.99" }, → PDF + Mailed (Best Value) .. $29.99 { "name":"PDF & Mailed Certificate","price":"27.99" } // = mailed-only price → data error ]
Also
robots.txt → Disallow: /programs/fees (the path the live prices load from, invisible to crawlers)Course schema on the same page says $15.99 / $27.99.What happens. When a learner finishes free study, the "buy your certificate" CTA drops them into /student/register/step-1.php, a legacy .php flow on the Sucuri-fronted custom site (a path your robots.txt disallows). And the company/group path, the highest-value buyer, is a "Request a Business or Educator Account" lead form that ends with "By submitting, you agree to be contacted about this request." It's a request, not a purchase.
Why it costs certificate sales: "buy certificates for my crew's completed courses" or "enroll my company in the 500-series" have no self-serve, agent-fulfillable path. The buyer most worth serving fast, a safety manager certifying a team, hits a callback funnel instead of a bookable checkout.
The proof
href="../../student/register/step-1.php" (robots.txt: Disallow: /student)Evidence log: method & dates
| Check | Method | Result |
|---|---|---|
| Canonical served site | curl -IL | www.oshacademy.com = 200; oshatrain.org = 307 (Sucuri), both behind Sucuri Cloudproxy |
| Agent-commerce on store | GET /.well-known/ucp, /llms.txt | UCP 2026-04-08, MCP endpoint, Shop Pay/Google Pay, both 200 |
| Agent-legibility on main site | GET /llms.txt, /sitemap.xml | both 404; no /.well-known/ucp |
| Structured data (rendered DOM) | Playwright (Chrome, 2× DPI) | course=1 · program=1 · home=1 · catalog=0 · business=0 |
| Certificate price integrity | schema Offer vs rendered | schema $15.99/$27.99/$27.99 vs live $16.99/$29.99 |
| Purchase & company path | DOM href + page copy | /student/register/step-1.php; "agree to be contacted" form |
| Errors (rendered) | pageerror / console listeners | home pageerror=0; gtag is not defined throws on course/program/catalog/business |
ERR_FAILED console entries and failed requests, these were induced by our own webfont blocking during screenshotting (a standard trick to beat screenshot hangs), not OSHAcademy defects. The one meaningful client-side error is the ReferenceError: gtag is not defined thrown by the pages' own analytics on the course/program/catalog/business pages (not the home page), worth a look, since it's the tracking that would measure the certificate funnel. All recon was passive: normal-browser navigation and standard public GETs of pages OSHAcademy serves any visitor (plus the store's own published llms.txt / /.well-known/ucp discovery docs). No account was created, no form submitted, no endpoint probed, no robots.txt-disallowed path crawled, no wall routed around. Dates: 2026-07-12.The opportunity
Reconcile the certificate price into one honest Offer; mark up the catalog hub and the company page; and put a bookable, agent-friendly certificate checkout where the "we'll contact you" form is, pointing the agent-commerce capability you already ship at the certificate business. The next two pages show it in your own brand, and hand you the files any AI needs to represent OSHAcademy accurately.