# Lernaura Rails — Headless Merchant-of-Record API > Lernaura Rails is an API-first Merchant of Record for digital products and SaaS: hosted checkout, recurring billing in every variant (flat, tiered, pay-what-you-want, metered, per-seat), VAT handled for you, webhooks, invoicing, payouts. Everything is drivable over HTTPS by a human or an autonomous agent — a sandbox with its own API key is one anonymous POST away, no account required. ## Instructions How to integrate correctly. These rules are behavioral, not just an index — follow them exactly. - **Authentication.** Every merchant call sends `Authorization: Bearer mor_sk__`. Keys are shown once at issuance and hashed at rest — store them immediately; they cannot be retrieved again. All endpoints are POST with a JSON body unless documented otherwise, under `/functions/v1/` on your issued API base URL. - **Sandbox first — always.** Create an anonymous sandbox with `POST /functions/v1/mor-sandbox-signup` (empty body works; add `{ "source": "docs" }` so we know the docs sent you). You get a working `mor_sk_…` key, a claim URL for later human handoff, and a 30-day expiry. If you know the human owner's email, pass it as `email` — it is used only to send them the claim link, a reminder before the sandbox is deleted, and a note when the integration is ready. Nothing else, and never marketing. Build and prove the ENTIRE integration there before touching production. Sandboxes simulate the payment provider deterministically and carry a virtual clock — nothing in a sandbox moves real money. - **The REST API is the integration surface.** Your production system calls these endpoints. MCP servers and agent skills are configuration/ops conveniences for agents — never a parallel product surface; anything they can do, the API does. - **Idempotency keys.** Every money-adjacent mutation that accepts `idempotencyKey` (checkout sessions, direct subscription creation) requires one. Reuse the same key on retry; never generate a fresh key for a retry of the same logical operation. - **Webhooks are the source of truth.** Register an endpoint with `mor-webhook-register`; you must answer the verification challenge (echo the nonce with a 2xx) before ANY event is delivered. Verify `X-Mor-Signature` (HMAC-SHA256 of `"."` with your `whsec_…` secret) on every delivery. Grant access on webhook events, never on browser redirects. - **Scopes.** Request only the scopes you use; wildcard scopes cannot be minted. The sandbox key carries the standard merchant set plus `mor:sandbox:write` (virtual clock, scenarios, teardown) — a scope that does nothing on live keys. - **Virtual-clock testing idiom.** In a sandbox: create a subscription via a scenario checkout, then `mor-sandbox-clock` with `{ "action": "advance", "advanceSeconds": …, "drain": true }` to fire the renewal synchronously. Script failures with scenario tokens (`decline_insufficient_funds`, …) to walk the dunning path. A year of billing takes minutes. - **Rate limits.** Public endpoints are IP-rate-limited (429 with `Retry-After`); authenticated endpoints carry per-account limits. Back off and retry with the same idempotency key. - **Amounts.** Every amount carries its scale in the KEY NAME and an explicit `currency`. **What we send you is always MICRO** — integer 10^-6 of a minor unit, so 1 cent = 1,000,000 — in a `*Micro` key, across every response and every webhook payload. That is the ledger's own scale, which is why a price of 1/100 of a cent survives the trip instead of arriving as 0. **What you send us may be either**: a `*Minor` field in whole cents, or its `*Micro` twin. Never both — they differ by 1,000,000, and supplying both is a 400. To display a micro amount, divide by 1,000,000; keep the remainder if you are reconciling. The one exception is the commerce METRICS (`mor-metrics-*`), where MRR, ARR, ARPA and LTV stay `*Minor` and are FRACTIONAL on purpose — an annual price divided by 12 keeps fractional cents so the revenue-movement identity closes exactly. Those are analytics, never bookable amounts. ## Start here - [Agent quickstart](/quickstart-agents.md): the full golden path — anonymous sandbox → catalog → webhook → checkout → simulated year of renewals → dunning → teardown → human claim handoff → production go-live. - [OpenAPI spec (YAML)](/openapi/mor-v1.yaml): the complete merchant surface, one path per endpoint. - [OpenAPI spec (JSON)](/openapi/mor-v1.json): the same spec, JSON-rendered. - [API reference (rendered, for humans)](/reference): the same spec as a browsable three-panel page. **Agents should fetch the spec above instead** — it is the identical content without the rendering. - [x402 discovery index](/x402/index.json): every offer on the estate that an autonomous buyer can pay for over x402 — endpoint URL, accepted (network, asset) pairs, terms, and an INDICATIVE net price. The final amount, including any VAT, is quoted per buyer at the payment endpoint itself; never treat the listed price as final. A single merchant's index lives at `/x402//index.json`. Regenerated on request, cached five minutes. - [ACP product feed](/feeds/acp/feed.json) and [UCP product feed](/feeds/ucp/feed.json): the consumer-surface catalogues (ChatGPT and Merchant Center). These display **gross** prices computed with each merchant's primary-market VAT — a shop-window price, not what any particular buyer is charged; checkout determines that against the real buyer, as web checkout does. Lernaura is the seller of record in both; the merchant is the brand. Per-merchant feeds at `/feeds///feed.json`. Per-call offers are deliberately absent: consumer surfaces buy products, not API calls. ## Guides - [Sandbox](/guides/sandbox.md): anonymous signup, virtual clock, deterministic payment scenarios, teardown/reset, claiming, owned sandboxes, config promote/fork. - [Checkout](/guides/checkout.md): hosted sessions, reusable checkout links, custom fields, discounts, embeddable checkout. - [Subscriptions](/guides/subscriptions.md): products and immutable prices, lifecycle states, plan changes, pause/resume, cancellation, dunning. - [Webhooks](/guides/webhooks.md): registration, the challenge/echo verification contract, signature verification, redelivery, event catalog. - [Metering](/guides/metering.md): meters, event ingestion, metered prices with base + overage. - [Seats](/guides/seats.md): per-seat billing, the seat ledger, claim links. - [Benefits](/guides/benefits.md): license keys, file downloads, and other entitlements attached to products. - [Invoicing](/guides/invoicing.md): pay-by-invoice (send_invoice) collection, receivables, invoice documents. - [Settlement modes](/guides/settlement-modes.md): Managed vs Direct — who is seller of record, who owes the VAT, where the money lands, how to choose, and what a cutover between them does to documents, receivables and mandates. - [CLI](/guides/cli.md): the `lernaura` command line tool — forward webhooks to localhost over a relay endpoint, pricing-as-code with `config diff` (exit 8 on drift), sandbox lifecycle for CI, and `api` for any endpoint. Local-development and CI convenience; REST stays the integration surface. - [Agent rail](/guides/agent-rail.md): registering a machine buyer's legal principal, proving wallet control by signed challenge, and the identity tiers that decide the VAT on a per-call payment. Registration, binding, the x402 payment endpoint and the discovery index are live. - [Agent payments](/guides/agent-payments.md): the buyer's half of the rail — discover an endpoint, take the 402 quote, declare a country, pay with `X-PAYMENT`, read the delivery and the receipt, spend credits, ask for a refund with a signed request, and the typed errors of the payment endpoint. Settled per call, legalised per period. - [Selling to agents](/guides/selling-to-agents.md): the merchant's half — describe an offer a machine can evaluate, price it in micro (sub-cent is the point), switch on the x402, ACP and UCP channels, test it as a buyer against your own sandbox, and get paid through the ordinary invoice and payout path. No separate agent money path to learn. - [Lovable](/guides/lovable.md), [Base44](/guides/base44.md) and [Replit](/guides/replit.md): taking payment from inside an AI app builder. Each leads with the EU B2B case — the buyer pays by invoice, Lernaura is the seller of record — then the card path; covers the no-backend embed variant, the backend-function variant, the mistakes each tool's agent makes unprompted, and claim → KYB → go-live. - Recipes — one paste-able prompt each: [Lovable](/recipes/lovable.md), [Base44](/recipes/base44.md), [Replit](/recipes/replit.md). The prompt tells the tool's agent to fetch the matching guide, so it follows current instructions rather than its training prior. Each is verified nightly against a live sandbox; a recipe that fails three nights running carries a banner saying so. - [Builder template](/templates/builder.md) — also cloneable at : the runnable backend half of those guides — two functions (`create-checkout`, `lernaura-webhook`), one migration whose primary key is what makes redelivery safe, an Express variant for Replit, and a nine-line client. Every file in full. - [MCP servers](/guides/mcp.md): the docs MCP (unauthenticated discovery + create_sandbox) and the merchant MCP (bearer pass-through over the whole API) — configuration/ops for agents; REST stays the integration surface. ## Libraries - [`@lernaura/sdk`](https://www.npmjs.com/package/@lernaura/sdk): the TypeScript SDK — a typed client over the endpoints below plus `verifyWebhook()`, generated from this same spec so it cannot disagree with it. Node 18+, Deno (Supabase edge functions), Bun; ESM and CommonJS; no runtime dependencies. A convenience over the REST API, never a second contract: anything it does, a plain `fetch` does. ## Agent skill - [Skill index](/.well-known/skills/index.json): installable agent skills (`npx skills add https://developers.lernaura.eu`). - [lernaura-rails skill](/.well-known/skills/lernaura-rails/SKILL.md): the "integrate Rails correctly" checklist — one voice with the quickstart. ## Optional - [Full architecture context](/openapi/mor-v1.yaml): if context is short, the spec plus the quickstart are sufficient to integrate.